PageRenderTime 70ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

/orm/orm_test.go

https://github.com/DeanHH/beego
Go | 1779 lines | 1430 code | 318 blank | 31 comment | 126 complexity | f3825907d38c5efaf2c4a92bcf795c9c MD5 | raw file
Possible License(s): Apache-2.0
  1. // Beego (http://beego.me/)
  2. // @description beego is an open-source, high-performance web framework for the Go programming language.
  3. // @link http://github.com/astaxie/beego for the canonical source repository
  4. // @license http://github.com/astaxie/beego/blob/master/LICENSE
  5. // @authors astaxie, slene
  6. package orm
  7. import (
  8. "bytes"
  9. "database/sql"
  10. "fmt"
  11. "io/ioutil"
  12. "os"
  13. "path/filepath"
  14. "reflect"
  15. "runtime"
  16. "strings"
  17. "testing"
  18. "time"
  19. )
  20. var _ = os.PathSeparator
  21. var (
  22. test_Date = format_Date + " -0700"
  23. test_DateTime = format_DateTime + " -0700"
  24. )
  25. func ValuesCompare(is bool, a interface{}, args ...interface{}) (err error, ok bool) {
  26. if len(args) == 0 {
  27. return fmt.Errorf("miss args"), false
  28. }
  29. b := args[0]
  30. arg := argAny(args)
  31. switch v := a.(type) {
  32. case reflect.Kind:
  33. ok = reflect.ValueOf(b).Kind() == v
  34. case time.Time:
  35. if v2, vo := b.(time.Time); vo {
  36. if arg.Get(1) != nil {
  37. format := ToStr(arg.Get(1))
  38. a = v.Format(format)
  39. b = v2.Format(format)
  40. ok = a == b
  41. } else {
  42. err = fmt.Errorf("compare datetime miss format")
  43. goto wrongArg
  44. }
  45. }
  46. default:
  47. ok = ToStr(a) == ToStr(b)
  48. }
  49. ok = is && ok || !is && !ok
  50. if !ok {
  51. if is {
  52. err = fmt.Errorf("expected: `%v`, get `%v`", b, a)
  53. } else {
  54. err = fmt.Errorf("expected: `%v`, get `%v`", b, a)
  55. }
  56. }
  57. wrongArg:
  58. if err != nil {
  59. return err, false
  60. }
  61. return nil, true
  62. }
  63. func AssertIs(a interface{}, args ...interface{}) error {
  64. if err, ok := ValuesCompare(true, a, args...); ok == false {
  65. return err
  66. }
  67. return nil
  68. }
  69. func AssertNot(a interface{}, args ...interface{}) error {
  70. if err, ok := ValuesCompare(false, a, args...); ok == false {
  71. return err
  72. }
  73. return nil
  74. }
  75. func getCaller(skip int) string {
  76. pc, file, line, _ := runtime.Caller(skip)
  77. fun := runtime.FuncForPC(pc)
  78. _, fn := filepath.Split(file)
  79. data, err := ioutil.ReadFile(file)
  80. var codes []string
  81. if err == nil {
  82. lines := bytes.Split(data, []byte{'\n'})
  83. n := 10
  84. for i := 0; i < n; i++ {
  85. o := line - n
  86. if o < 0 {
  87. continue
  88. }
  89. cur := o + i + 1
  90. flag := " "
  91. if cur == line {
  92. flag = ">>"
  93. }
  94. code := fmt.Sprintf(" %s %5d: %s", flag, cur, strings.Replace(string(lines[o+i]), "\t", " ", -1))
  95. if code != "" {
  96. codes = append(codes, code)
  97. }
  98. }
  99. }
  100. funName := fun.Name()
  101. if i := strings.LastIndex(funName, "."); i > -1 {
  102. funName = funName[i+1:]
  103. }
  104. return fmt.Sprintf("%s:%d: \n%s", fn, line, strings.Join(codes, "\n"))
  105. }
  106. func throwFail(t *testing.T, err error, args ...interface{}) {
  107. if err != nil {
  108. con := fmt.Sprintf("\t\nError: %s\n%s\n", err.Error(), getCaller(2))
  109. if len(args) > 0 {
  110. parts := make([]string, 0, len(args))
  111. for _, arg := range args {
  112. parts = append(parts, fmt.Sprintf("%v", arg))
  113. }
  114. con += " " + strings.Join(parts, ", ")
  115. }
  116. t.Error(con)
  117. t.Fail()
  118. }
  119. }
  120. func throwFailNow(t *testing.T, err error, args ...interface{}) {
  121. if err != nil {
  122. con := fmt.Sprintf("\t\nError: %s\n%s\n", err.Error(), getCaller(2))
  123. if len(args) > 0 {
  124. parts := make([]string, 0, len(args))
  125. for _, arg := range args {
  126. parts = append(parts, fmt.Sprintf("%v", arg))
  127. }
  128. con += " " + strings.Join(parts, ", ")
  129. }
  130. t.Error(con)
  131. t.FailNow()
  132. }
  133. }
  134. func TestGetDB(t *testing.T) {
  135. if db, err := GetDB(); err != nil {
  136. throwFailNow(t, err)
  137. } else {
  138. err = db.Ping()
  139. throwFailNow(t, err)
  140. }
  141. }
  142. func TestSyncDb(t *testing.T) {
  143. RegisterModel(new(Data), new(DataNull), new(DataCustom))
  144. RegisterModel(new(User))
  145. RegisterModel(new(Profile))
  146. RegisterModel(new(Post))
  147. RegisterModel(new(Tag))
  148. RegisterModel(new(Comment))
  149. RegisterModel(new(UserBig))
  150. RegisterModel(new(PostTags))
  151. err := RunSyncdb("default", true, false)
  152. throwFail(t, err)
  153. modelCache.clean()
  154. }
  155. func TestRegisterModels(t *testing.T) {
  156. RegisterModel(new(Data), new(DataNull), new(DataCustom))
  157. RegisterModel(new(User))
  158. RegisterModel(new(Profile))
  159. RegisterModel(new(Post))
  160. RegisterModel(new(Tag))
  161. RegisterModel(new(Comment))
  162. RegisterModel(new(UserBig))
  163. RegisterModel(new(PostTags))
  164. BootStrap()
  165. dORM = NewOrm()
  166. dDbBaser = getDbAlias("default").DbBaser
  167. }
  168. func TestModelSyntax(t *testing.T) {
  169. user := &User{}
  170. ind := reflect.ValueOf(user).Elem()
  171. fn := getFullName(ind.Type())
  172. mi, ok := modelCache.getByFN(fn)
  173. throwFail(t, AssertIs(ok, true))
  174. mi, ok = modelCache.get("user")
  175. throwFail(t, AssertIs(ok, true))
  176. if ok {
  177. throwFail(t, AssertIs(mi.fields.GetByName("ShouldSkip") == nil, true))
  178. }
  179. }
  180. var Data_Values = map[string]interface{}{
  181. "Boolean": true,
  182. "Char": "char",
  183. "Text": "text",
  184. "Date": time.Now(),
  185. "DateTime": time.Now(),
  186. "Byte": byte(1<<8 - 1),
  187. "Rune": rune(1<<31 - 1),
  188. "Int": int(1<<31 - 1),
  189. "Int8": int8(1<<7 - 1),
  190. "Int16": int16(1<<15 - 1),
  191. "Int32": int32(1<<31 - 1),
  192. "Int64": int64(1<<63 - 1),
  193. "Uint": uint(1<<32 - 1),
  194. "Uint8": uint8(1<<8 - 1),
  195. "Uint16": uint16(1<<16 - 1),
  196. "Uint32": uint32(1<<32 - 1),
  197. "Uint64": uint64(1<<63 - 1), // uint64 values with high bit set are not supported
  198. "Float32": float32(100.1234),
  199. "Float64": float64(100.1234),
  200. "Decimal": float64(100.1234),
  201. }
  202. func TestDataTypes(t *testing.T) {
  203. d := Data{}
  204. ind := reflect.Indirect(reflect.ValueOf(&d))
  205. for name, value := range Data_Values {
  206. e := ind.FieldByName(name)
  207. e.Set(reflect.ValueOf(value))
  208. }
  209. id, err := dORM.Insert(&d)
  210. throwFail(t, err)
  211. throwFail(t, AssertIs(id, 1))
  212. d = Data{Id: 1}
  213. err = dORM.Read(&d)
  214. throwFail(t, err)
  215. ind = reflect.Indirect(reflect.ValueOf(&d))
  216. for name, value := range Data_Values {
  217. e := ind.FieldByName(name)
  218. vu := e.Interface()
  219. switch name {
  220. case "Date":
  221. vu = vu.(time.Time).In(DefaultTimeLoc).Format(test_Date)
  222. value = value.(time.Time).In(DefaultTimeLoc).Format(test_Date)
  223. case "DateTime":
  224. vu = vu.(time.Time).In(DefaultTimeLoc).Format(test_DateTime)
  225. value = value.(time.Time).In(DefaultTimeLoc).Format(test_DateTime)
  226. }
  227. throwFail(t, AssertIs(vu == value, true), value, vu)
  228. }
  229. }
  230. func TestNullDataTypes(t *testing.T) {
  231. d := DataNull{}
  232. if IsPostgres {
  233. // can removed when this fixed
  234. // https://github.com/lib/pq/pull/125
  235. d.DateTime = time.Now()
  236. }
  237. id, err := dORM.Insert(&d)
  238. throwFail(t, err)
  239. throwFail(t, AssertIs(id, 1))
  240. d = DataNull{Id: 1}
  241. err = dORM.Read(&d)
  242. throwFail(t, err)
  243. throwFail(t, AssertIs(d.NullBool.Valid, false))
  244. throwFail(t, AssertIs(d.NullString.Valid, false))
  245. throwFail(t, AssertIs(d.NullInt64.Valid, false))
  246. throwFail(t, AssertIs(d.NullFloat64.Valid, false))
  247. _, err = dORM.Raw(`INSERT INTO data_null (boolean) VALUES (?)`, nil).Exec()
  248. throwFail(t, err)
  249. d = DataNull{Id: 2}
  250. err = dORM.Read(&d)
  251. throwFail(t, err)
  252. d = DataNull{
  253. DateTime: time.Now(),
  254. NullString: sql.NullString{String: "test", Valid: true},
  255. NullBool: sql.NullBool{Bool: true, Valid: true},
  256. NullInt64: sql.NullInt64{Int64: 42, Valid: true},
  257. NullFloat64: sql.NullFloat64{Float64: 42.42, Valid: true},
  258. }
  259. id, err = dORM.Insert(&d)
  260. throwFail(t, err)
  261. throwFail(t, AssertIs(id, 3))
  262. d = DataNull{Id: 3}
  263. err = dORM.Read(&d)
  264. throwFail(t, err)
  265. throwFail(t, AssertIs(d.NullBool.Valid, true))
  266. throwFail(t, AssertIs(d.NullBool.Bool, true))
  267. throwFail(t, AssertIs(d.NullString.Valid, true))
  268. throwFail(t, AssertIs(d.NullString.String, "test"))
  269. throwFail(t, AssertIs(d.NullInt64.Valid, true))
  270. throwFail(t, AssertIs(d.NullInt64.Int64, 42))
  271. throwFail(t, AssertIs(d.NullFloat64.Valid, true))
  272. throwFail(t, AssertIs(d.NullFloat64.Float64, 42.42))
  273. }
  274. func TestDataCustomTypes(t *testing.T) {
  275. d := DataCustom{}
  276. ind := reflect.Indirect(reflect.ValueOf(&d))
  277. for name, value := range Data_Values {
  278. e := ind.FieldByName(name)
  279. if !e.IsValid() {
  280. continue
  281. }
  282. e.Set(reflect.ValueOf(value).Convert(e.Type()))
  283. }
  284. id, err := dORM.Insert(&d)
  285. throwFail(t, err)
  286. throwFail(t, AssertIs(id, 1))
  287. d = DataCustom{Id: 1}
  288. err = dORM.Read(&d)
  289. throwFail(t, err)
  290. ind = reflect.Indirect(reflect.ValueOf(&d))
  291. for name, value := range Data_Values {
  292. e := ind.FieldByName(name)
  293. if !e.IsValid() {
  294. continue
  295. }
  296. vu := e.Interface()
  297. value = reflect.ValueOf(value).Convert(e.Type()).Interface()
  298. throwFail(t, AssertIs(vu == value, true), value, vu)
  299. }
  300. }
  301. func TestCRUD(t *testing.T) {
  302. profile := NewProfile()
  303. profile.Age = 30
  304. profile.Money = 1234.12
  305. id, err := dORM.Insert(profile)
  306. throwFail(t, err)
  307. throwFail(t, AssertIs(id, 1))
  308. user := NewUser()
  309. user.UserName = "slene"
  310. user.Email = "vslene@gmail.com"
  311. user.Password = "pass"
  312. user.Status = 3
  313. user.IsStaff = true
  314. user.IsActive = true
  315. id, err = dORM.Insert(user)
  316. throwFail(t, err)
  317. throwFail(t, AssertIs(id, 1))
  318. u := &User{Id: user.Id}
  319. err = dORM.Read(u)
  320. throwFail(t, err)
  321. throwFail(t, AssertIs(u.UserName, "slene"))
  322. throwFail(t, AssertIs(u.Email, "vslene@gmail.com"))
  323. throwFail(t, AssertIs(u.Password, "pass"))
  324. throwFail(t, AssertIs(u.Status, 3))
  325. throwFail(t, AssertIs(u.IsStaff, true))
  326. throwFail(t, AssertIs(u.IsActive, true))
  327. throwFail(t, AssertIs(u.Created.In(DefaultTimeLoc), user.Created.In(DefaultTimeLoc), test_Date))
  328. throwFail(t, AssertIs(u.Updated.In(DefaultTimeLoc), user.Updated.In(DefaultTimeLoc), test_DateTime))
  329. user.UserName = "astaxie"
  330. user.Profile = profile
  331. num, err := dORM.Update(user)
  332. throwFail(t, err)
  333. throwFail(t, AssertIs(num, 1))
  334. u = &User{Id: user.Id}
  335. err = dORM.Read(u)
  336. throwFailNow(t, err)
  337. throwFail(t, AssertIs(u.UserName, "astaxie"))
  338. throwFail(t, AssertIs(u.Profile.Id, profile.Id))
  339. u = &User{UserName: "astaxie", Password: "pass"}
  340. err = dORM.Read(u, "UserName")
  341. throwFailNow(t, err)
  342. throwFailNow(t, AssertIs(id, 1))
  343. u.UserName = "QQ"
  344. u.Password = "111"
  345. num, err = dORM.Update(u, "UserName")
  346. throwFail(t, err)
  347. throwFail(t, AssertIs(num, 1))
  348. u = &User{Id: user.Id}
  349. err = dORM.Read(u)
  350. throwFailNow(t, err)
  351. throwFail(t, AssertIs(u.UserName, "QQ"))
  352. throwFail(t, AssertIs(u.Password, "pass"))
  353. num, err = dORM.Delete(profile)
  354. throwFail(t, err)
  355. throwFail(t, AssertIs(num, 1))
  356. u = &User{Id: user.Id}
  357. err = dORM.Read(u)
  358. throwFail(t, err)
  359. throwFail(t, AssertIs(true, u.Profile == nil))
  360. num, err = dORM.Delete(user)
  361. throwFail(t, err)
  362. throwFail(t, AssertIs(num, 1))
  363. u = &User{Id: 100}
  364. err = dORM.Read(u)
  365. throwFail(t, AssertIs(err, ErrNoRows))
  366. ub := UserBig{}
  367. ub.Name = "name"
  368. id, err = dORM.Insert(&ub)
  369. throwFail(t, err)
  370. throwFail(t, AssertIs(id, 1))
  371. ub = UserBig{Id: 1}
  372. err = dORM.Read(&ub)
  373. throwFail(t, err)
  374. throwFail(t, AssertIs(ub.Name, "name"))
  375. }
  376. func TestInsertTestData(t *testing.T) {
  377. var users []*User
  378. profile := NewProfile()
  379. profile.Age = 28
  380. profile.Money = 1234.12
  381. id, err := dORM.Insert(profile)
  382. throwFail(t, err)
  383. throwFail(t, AssertIs(id, 2))
  384. user := NewUser()
  385. user.UserName = "slene"
  386. user.Email = "vslene@gmail.com"
  387. user.Password = "pass"
  388. user.Status = 1
  389. user.IsStaff = false
  390. user.IsActive = true
  391. user.Profile = profile
  392. users = append(users, user)
  393. id, err = dORM.Insert(user)
  394. throwFail(t, err)
  395. throwFail(t, AssertIs(id, 2))
  396. profile = NewProfile()
  397. profile.Age = 30
  398. profile.Money = 4321.09
  399. id, err = dORM.Insert(profile)
  400. throwFail(t, err)
  401. throwFail(t, AssertIs(id, 3))
  402. user = NewUser()
  403. user.UserName = "astaxie"
  404. user.Email = "astaxie@gmail.com"
  405. user.Password = "password"
  406. user.Status = 2
  407. user.IsStaff = true
  408. user.IsActive = false
  409. user.Profile = profile
  410. users = append(users, user)
  411. id, err = dORM.Insert(user)
  412. throwFail(t, err)
  413. throwFail(t, AssertIs(id, 3))
  414. user = NewUser()
  415. user.UserName = "nobody"
  416. user.Email = "nobody@gmail.com"
  417. user.Password = "nobody"
  418. user.Status = 3
  419. user.IsStaff = false
  420. user.IsActive = false
  421. users = append(users, user)
  422. id, err = dORM.Insert(user)
  423. throwFail(t, err)
  424. throwFail(t, AssertIs(id, 4))
  425. tags := []*Tag{
  426. &Tag{Name: "golang", BestPost: &Post{Id: 2}},
  427. &Tag{Name: "example"},
  428. &Tag{Name: "format"},
  429. &Tag{Name: "c++"},
  430. }
  431. posts := []*Post{
  432. &Post{User: users[0], Tags: []*Tag{tags[0]}, Title: "Introduction", Content: `Go is a new language. Although it borrows ideas from existing languages, it has unusual properties that make effective Go programs different in character from programs written in its relatives. A straightforward translation of a C++ or Java program into Go is unlikely to produce a satisfactory result—Java programs are written in Java, not Go. On the other hand, thinking about the problem from a Go perspective could produce a successful but quite different program. In other words, to write Go well, it's important to understand its properties and idioms. It's also important to know the established conventions for programming in Go, such as naming, formatting, program construction, and so on, so that programs you write will be easy for other Go programmers to understand.
  433. This document gives tips for writing clear, idiomatic Go code. It augments the language specification, the Tour of Go, and How to Write Go Code, all of which you should read first.`},
  434. &Post{User: users[1], Tags: []*Tag{tags[0], tags[1]}, Title: "Examples", Content: `The Go package sources are intended to serve not only as the core library but also as examples of how to use the language. Moreover, many of the packages contain working, self-contained executable examples you can run directly from the golang.org web site, such as this one (click on the word "Example" to open it up). If you have a question about how to approach a problem or how something might be implemented, the documentation, code and examples in the library can provide answers, ideas and background.`},
  435. &Post{User: users[1], Tags: []*Tag{tags[0], tags[2]}, Title: "Formatting", Content: `Formatting issues are the most contentious but the least consequential. People can adapt to different formatting styles but it's better if they don't have to, and less time is devoted to the topic if everyone adheres to the same style. The problem is how to approach this Utopia without a long prescriptive style guide.
  436. With Go we take an unusual approach and let the machine take care of most formatting issues. The gofmt program (also available as go fmt, which operates at the package level rather than source file level) reads a Go program and emits the source in a standard style of indentation and vertical alignment, retaining and if necessary reformatting comments. If you want to know how to handle some new layout situation, run gofmt; if the answer doesn't seem right, rearrange your program (or file a bug about gofmt), don't work around it.`},
  437. &Post{User: users[2], Tags: []*Tag{tags[3]}, Title: "Commentary", Content: `Go provides C-style /* */ block comments and C++-style // line comments. Line comments are the norm; block comments appear mostly as package comments, but are useful within an expression or to disable large swaths of code.
  438. The program—and web server—godoc processes Go source files to extract documentation about the contents of the package. Comments that appear before top-level declarations, with no intervening newlines, are extracted along with the declaration to serve as explanatory text for the item. The nature and style of these comments determines the quality of the documentation godoc produces.`},
  439. }
  440. comments := []*Comment{
  441. &Comment{Post: posts[0], Content: "a comment"},
  442. &Comment{Post: posts[1], Content: "yes"},
  443. &Comment{Post: posts[1]},
  444. &Comment{Post: posts[1]},
  445. &Comment{Post: posts[2]},
  446. &Comment{Post: posts[2]},
  447. }
  448. for _, tag := range tags {
  449. id, err := dORM.Insert(tag)
  450. throwFail(t, err)
  451. throwFail(t, AssertIs(id > 0, true))
  452. }
  453. for _, post := range posts {
  454. id, err := dORM.Insert(post)
  455. throwFail(t, err)
  456. throwFail(t, AssertIs(id > 0, true))
  457. num := len(post.Tags)
  458. if num > 0 {
  459. nums, err := dORM.QueryM2M(post, "tags").Add(post.Tags)
  460. throwFailNow(t, err)
  461. throwFailNow(t, AssertIs(nums, num))
  462. }
  463. }
  464. for _, comment := range comments {
  465. id, err := dORM.Insert(comment)
  466. throwFail(t, err)
  467. throwFail(t, AssertIs(id > 0, true))
  468. }
  469. }
  470. func TestCustomField(t *testing.T) {
  471. user := User{Id: 2}
  472. err := dORM.Read(&user)
  473. throwFailNow(t, err)
  474. user.Langs = append(user.Langs, "zh-CN", "en-US")
  475. user.Extra.Name = "beego"
  476. user.Extra.Data = "orm"
  477. _, err = dORM.Update(&user, "Langs", "Extra")
  478. throwFailNow(t, err)
  479. user = User{Id: 2}
  480. err = dORM.Read(&user)
  481. throwFailNow(t, err)
  482. throwFailNow(t, AssertIs(len(user.Langs), 2))
  483. throwFailNow(t, AssertIs(user.Langs[0], "zh-CN"))
  484. throwFailNow(t, AssertIs(user.Langs[1], "en-US"))
  485. throwFailNow(t, AssertIs(user.Extra.Name, "beego"))
  486. throwFailNow(t, AssertIs(user.Extra.Data, "orm"))
  487. }
  488. func TestExpr(t *testing.T) {
  489. user := &User{}
  490. qs := dORM.QueryTable(user)
  491. qs = dORM.QueryTable((*User)(nil))
  492. qs = dORM.QueryTable("User")
  493. qs = dORM.QueryTable("user")
  494. num, err := qs.Filter("UserName", "slene").Filter("user_name", "slene").Filter("profile__Age", 28).Count()
  495. throwFail(t, err)
  496. throwFail(t, AssertIs(num, 1))
  497. num, err = qs.Filter("created", time.Now()).Count()
  498. throwFail(t, err)
  499. throwFail(t, AssertIs(num, 3))
  500. // num, err = qs.Filter("created", time.Now().Format(format_Date)).Count()
  501. // throwFail(t, err)
  502. // throwFail(t, AssertIs(num, 3))
  503. }
  504. func TestOperators(t *testing.T) {
  505. qs := dORM.QueryTable("user")
  506. num, err := qs.Filter("user_name", "slene").Count()
  507. throwFail(t, err)
  508. throwFail(t, AssertIs(num, 1))
  509. num, err = qs.Filter("user_name__exact", String("slene")).Count()
  510. throwFail(t, err)
  511. throwFail(t, AssertIs(num, 1))
  512. num, err = qs.Filter("user_name__exact", "slene").Count()
  513. throwFail(t, err)
  514. throwFail(t, AssertIs(num, 1))
  515. num, err = qs.Filter("user_name__iexact", "Slene").Count()
  516. throwFail(t, err)
  517. throwFail(t, AssertIs(num, 1))
  518. num, err = qs.Filter("user_name__contains", "e").Count()
  519. throwFail(t, err)
  520. throwFail(t, AssertIs(num, 2))
  521. var shouldNum int
  522. if IsSqlite {
  523. shouldNum = 2
  524. } else {
  525. shouldNum = 0
  526. }
  527. num, err = qs.Filter("user_name__contains", "E").Count()
  528. throwFail(t, err)
  529. throwFail(t, AssertIs(num, shouldNum))
  530. num, err = qs.Filter("user_name__icontains", "E").Count()
  531. throwFail(t, err)
  532. throwFail(t, AssertIs(num, 2))
  533. num, err = qs.Filter("user_name__icontains", "E").Count()
  534. throwFail(t, err)
  535. throwFail(t, AssertIs(num, 2))
  536. num, err = qs.Filter("status__gt", 1).Count()
  537. throwFail(t, err)
  538. throwFail(t, AssertIs(num, 2))
  539. num, err = qs.Filter("status__gte", 1).Count()
  540. throwFail(t, err)
  541. throwFail(t, AssertIs(num, 3))
  542. num, err = qs.Filter("status__lt", Uint(3)).Count()
  543. throwFail(t, err)
  544. throwFail(t, AssertIs(num, 2))
  545. num, err = qs.Filter("status__lte", Int(3)).Count()
  546. throwFail(t, err)
  547. throwFail(t, AssertIs(num, 3))
  548. num, err = qs.Filter("user_name__startswith", "s").Count()
  549. throwFail(t, err)
  550. throwFail(t, AssertIs(num, 1))
  551. if IsSqlite {
  552. shouldNum = 1
  553. } else {
  554. shouldNum = 0
  555. }
  556. num, err = qs.Filter("user_name__startswith", "S").Count()
  557. throwFail(t, err)
  558. throwFail(t, AssertIs(num, shouldNum))
  559. num, err = qs.Filter("user_name__istartswith", "S").Count()
  560. throwFail(t, err)
  561. throwFail(t, AssertIs(num, 1))
  562. num, err = qs.Filter("user_name__endswith", "e").Count()
  563. throwFail(t, err)
  564. throwFail(t, AssertIs(num, 2))
  565. if IsSqlite {
  566. shouldNum = 2
  567. } else {
  568. shouldNum = 0
  569. }
  570. num, err = qs.Filter("user_name__endswith", "E").Count()
  571. throwFail(t, err)
  572. throwFail(t, AssertIs(num, shouldNum))
  573. num, err = qs.Filter("user_name__iendswith", "E").Count()
  574. throwFail(t, err)
  575. throwFail(t, AssertIs(num, 2))
  576. num, err = qs.Filter("profile__isnull", true).Count()
  577. throwFail(t, err)
  578. throwFail(t, AssertIs(num, 1))
  579. num, err = qs.Filter("status__in", 1, 2).Count()
  580. throwFail(t, err)
  581. throwFail(t, AssertIs(num, 2))
  582. num, err = qs.Filter("status__in", []int{1, 2}).Count()
  583. throwFail(t, err)
  584. throwFail(t, AssertIs(num, 2))
  585. n1, n2 := 1, 2
  586. num, err = qs.Filter("status__in", []*int{&n1}, &n2).Count()
  587. throwFail(t, err)
  588. throwFail(t, AssertIs(num, 2))
  589. num, err = qs.Filter("id__between", 2, 3).Count()
  590. throwFail(t, err)
  591. throwFail(t, AssertIs(num, 2))
  592. num, err = qs.Filter("id__between", []int{2, 3}).Count()
  593. throwFail(t, err)
  594. throwFail(t, AssertIs(num, 2))
  595. }
  596. func TestSetCond(t *testing.T) {
  597. cond := NewCondition()
  598. cond1 := cond.And("profile__isnull", false).AndNot("status__in", 1).Or("profile__age__gt", 2000)
  599. qs := dORM.QueryTable("user")
  600. num, err := qs.SetCond(cond1).Count()
  601. throwFail(t, err)
  602. throwFail(t, AssertIs(num, 1))
  603. cond2 := cond.AndCond(cond1).OrCond(cond.And("user_name", "slene"))
  604. num, err = qs.SetCond(cond2).Count()
  605. throwFail(t, err)
  606. throwFail(t, AssertIs(num, 2))
  607. }
  608. func TestLimit(t *testing.T) {
  609. var posts []*Post
  610. qs := dORM.QueryTable("post")
  611. num, err := qs.Limit(1).All(&posts)
  612. throwFail(t, err)
  613. throwFail(t, AssertIs(num, 1))
  614. num, err = qs.Limit(-1).All(&posts)
  615. throwFail(t, err)
  616. throwFail(t, AssertIs(num, 4))
  617. num, err = qs.Limit(-1, 2).All(&posts)
  618. throwFail(t, err)
  619. throwFail(t, AssertIs(num, 2))
  620. num, err = qs.Limit(0, 2).All(&posts)
  621. throwFail(t, err)
  622. throwFail(t, AssertIs(num, 2))
  623. }
  624. func TestOffset(t *testing.T) {
  625. var posts []*Post
  626. qs := dORM.QueryTable("post")
  627. num, err := qs.Limit(1).Offset(2).All(&posts)
  628. throwFail(t, err)
  629. throwFail(t, AssertIs(num, 1))
  630. num, err = qs.Offset(2).All(&posts)
  631. throwFail(t, err)
  632. throwFail(t, AssertIs(num, 2))
  633. }
  634. func TestOrderBy(t *testing.T) {
  635. qs := dORM.QueryTable("user")
  636. num, err := qs.OrderBy("-status").Filter("user_name", "nobody").Count()
  637. throwFail(t, err)
  638. throwFail(t, AssertIs(num, 1))
  639. num, err = qs.OrderBy("status").Filter("user_name", "slene").Count()
  640. throwFail(t, err)
  641. throwFail(t, AssertIs(num, 1))
  642. num, err = qs.OrderBy("-profile__age").Filter("user_name", "astaxie").Count()
  643. throwFail(t, err)
  644. throwFail(t, AssertIs(num, 1))
  645. }
  646. func TestAll(t *testing.T) {
  647. var users []*User
  648. qs := dORM.QueryTable("user")
  649. num, err := qs.OrderBy("Id").All(&users)
  650. throwFail(t, err)
  651. throwFailNow(t, AssertIs(num, 3))
  652. throwFail(t, AssertIs(users[0].UserName, "slene"))
  653. throwFail(t, AssertIs(users[1].UserName, "astaxie"))
  654. throwFail(t, AssertIs(users[2].UserName, "nobody"))
  655. var users2 []User
  656. qs = dORM.QueryTable("user")
  657. num, err = qs.OrderBy("Id").All(&users2)
  658. throwFail(t, err)
  659. throwFailNow(t, AssertIs(num, 3))
  660. throwFailNow(t, AssertIs(users2[0].UserName, "slene"))
  661. throwFailNow(t, AssertIs(users2[1].UserName, "astaxie"))
  662. throwFailNow(t, AssertIs(users2[2].UserName, "nobody"))
  663. qs = dORM.QueryTable("user")
  664. num, err = qs.OrderBy("Id").RelatedSel().All(&users2, "UserName")
  665. throwFail(t, err)
  666. throwFailNow(t, AssertIs(num, 3))
  667. throwFailNow(t, AssertIs(len(users2), 3))
  668. throwFailNow(t, AssertIs(users2[0].UserName, "slene"))
  669. throwFailNow(t, AssertIs(users2[1].UserName, "astaxie"))
  670. throwFailNow(t, AssertIs(users2[2].UserName, "nobody"))
  671. throwFailNow(t, AssertIs(users2[0].Id, 0))
  672. throwFailNow(t, AssertIs(users2[1].Id, 0))
  673. throwFailNow(t, AssertIs(users2[2].Id, 0))
  674. throwFailNow(t, AssertIs(users2[0].Profile == nil, false))
  675. throwFailNow(t, AssertIs(users2[1].Profile == nil, false))
  676. throwFailNow(t, AssertIs(users2[2].Profile == nil, true))
  677. qs = dORM.QueryTable("user")
  678. num, err = qs.Filter("user_name", "nothing").All(&users)
  679. throwFailNow(t, err)
  680. throwFailNow(t, AssertIs(num, 0))
  681. var users3 []*User
  682. qs = dORM.QueryTable("user")
  683. num, err = qs.Filter("user_name", "nothing").All(&users3)
  684. throwFailNow(t, AssertIs(users3 == nil, false))
  685. }
  686. func TestOne(t *testing.T) {
  687. var user User
  688. qs := dORM.QueryTable("user")
  689. err := qs.One(&user)
  690. throwFail(t, AssertIs(err, ErrMultiRows))
  691. user = User{}
  692. err = qs.OrderBy("Id").Limit(1).One(&user)
  693. throwFailNow(t, err)
  694. throwFail(t, AssertIs(user.UserName, "slene"))
  695. err = qs.Filter("user_name", "nothing").One(&user)
  696. throwFail(t, AssertIs(err, ErrNoRows))
  697. }
  698. func TestValues(t *testing.T) {
  699. var maps []Params
  700. qs := dORM.QueryTable("user")
  701. num, err := qs.OrderBy("Id").Values(&maps)
  702. throwFail(t, err)
  703. throwFail(t, AssertIs(num, 3))
  704. if num == 3 {
  705. throwFail(t, AssertIs(maps[0]["UserName"], "slene"))
  706. throwFail(t, AssertIs(maps[2]["Profile"], nil))
  707. }
  708. num, err = qs.OrderBy("Id").Values(&maps, "UserName", "Profile__Age")
  709. throwFail(t, err)
  710. throwFail(t, AssertIs(num, 3))
  711. if num == 3 {
  712. throwFail(t, AssertIs(maps[0]["UserName"], "slene"))
  713. throwFail(t, AssertIs(maps[0]["Profile__Age"], 28))
  714. throwFail(t, AssertIs(maps[2]["Profile__Age"], nil))
  715. }
  716. num, err = qs.Filter("UserName", "slene").Values(&maps)
  717. throwFail(t, err)
  718. throwFail(t, AssertIs(num, 1))
  719. }
  720. func TestValuesList(t *testing.T) {
  721. var list []ParamsList
  722. qs := dORM.QueryTable("user")
  723. num, err := qs.OrderBy("Id").ValuesList(&list)
  724. throwFail(t, err)
  725. throwFail(t, AssertIs(num, 3))
  726. if num == 3 {
  727. throwFail(t, AssertIs(list[0][1], "slene"))
  728. throwFail(t, AssertIs(list[2][9], nil))
  729. }
  730. num, err = qs.OrderBy("Id").ValuesList(&list, "UserName", "Profile__Age")
  731. throwFail(t, err)
  732. throwFail(t, AssertIs(num, 3))
  733. if num == 3 {
  734. throwFail(t, AssertIs(list[0][0], "slene"))
  735. throwFail(t, AssertIs(list[0][1], 28))
  736. throwFail(t, AssertIs(list[2][1], nil))
  737. }
  738. }
  739. func TestValuesFlat(t *testing.T) {
  740. var list ParamsList
  741. qs := dORM.QueryTable("user")
  742. num, err := qs.OrderBy("id").ValuesFlat(&list, "UserName")
  743. throwFail(t, err)
  744. throwFail(t, AssertIs(num, 3))
  745. if num == 3 {
  746. throwFail(t, AssertIs(list[0], "slene"))
  747. throwFail(t, AssertIs(list[1], "astaxie"))
  748. throwFail(t, AssertIs(list[2], "nobody"))
  749. }
  750. }
  751. func TestRelatedSel(t *testing.T) {
  752. qs := dORM.QueryTable("user")
  753. num, err := qs.Filter("profile__age", 28).Count()
  754. throwFail(t, err)
  755. throwFail(t, AssertIs(num, 1))
  756. num, err = qs.Filter("profile__age__gt", 28).Count()
  757. throwFail(t, err)
  758. throwFail(t, AssertIs(num, 1))
  759. num, err = qs.Filter("profile__user__profile__age__gt", 28).Count()
  760. throwFail(t, err)
  761. throwFail(t, AssertIs(num, 1))
  762. var user User
  763. err = qs.Filter("user_name", "slene").RelatedSel("profile").One(&user)
  764. throwFail(t, err)
  765. throwFail(t, AssertIs(num, 1))
  766. throwFail(t, AssertNot(user.Profile, nil))
  767. if user.Profile != nil {
  768. throwFail(t, AssertIs(user.Profile.Age, 28))
  769. }
  770. err = qs.Filter("user_name", "slene").RelatedSel().One(&user)
  771. throwFail(t, err)
  772. throwFail(t, AssertIs(num, 1))
  773. throwFail(t, AssertNot(user.Profile, nil))
  774. if user.Profile != nil {
  775. throwFail(t, AssertIs(user.Profile.Age, 28))
  776. }
  777. err = qs.Filter("user_name", "nobody").RelatedSel("profile").One(&user)
  778. throwFail(t, AssertIs(num, 1))
  779. throwFail(t, AssertIs(user.Profile, nil))
  780. qs = dORM.QueryTable("user_profile")
  781. num, err = qs.Filter("user__username", "slene").Count()
  782. throwFail(t, err)
  783. throwFail(t, AssertIs(num, 1))
  784. var posts []*Post
  785. qs = dORM.QueryTable("post")
  786. num, err = qs.RelatedSel().All(&posts)
  787. throwFail(t, err)
  788. throwFailNow(t, AssertIs(num, 4))
  789. throwFailNow(t, AssertIs(posts[0].User.UserName, "slene"))
  790. throwFailNow(t, AssertIs(posts[1].User.UserName, "astaxie"))
  791. throwFailNow(t, AssertIs(posts[2].User.UserName, "astaxie"))
  792. throwFailNow(t, AssertIs(posts[3].User.UserName, "nobody"))
  793. }
  794. func TestReverseQuery(t *testing.T) {
  795. var profile Profile
  796. err := dORM.QueryTable("user_profile").Filter("User", 3).One(&profile)
  797. throwFailNow(t, err)
  798. throwFailNow(t, AssertIs(profile.Age, 30))
  799. profile = Profile{}
  800. err = dORM.QueryTable("user_profile").Filter("User__UserName", "astaxie").One(&profile)
  801. throwFailNow(t, err)
  802. throwFailNow(t, AssertIs(profile.Age, 30))
  803. var user User
  804. err = dORM.QueryTable("user").Filter("Posts__Title", "Examples").One(&user)
  805. throwFailNow(t, err)
  806. throwFailNow(t, AssertIs(user.UserName, "astaxie"))
  807. user = User{}
  808. err = dORM.QueryTable("user").Filter("Posts__User__UserName", "astaxie").Limit(1).One(&user)
  809. throwFailNow(t, err)
  810. throwFailNow(t, AssertIs(user.UserName, "astaxie"))
  811. user = User{}
  812. err = dORM.QueryTable("user").Filter("Posts__User__UserName", "astaxie").RelatedSel().Limit(1).One(&user)
  813. throwFailNow(t, err)
  814. throwFailNow(t, AssertIs(user.UserName, "astaxie"))
  815. throwFailNow(t, AssertIs(user.Profile == nil, false))
  816. throwFailNow(t, AssertIs(user.Profile.Age, 30))
  817. var posts []*Post
  818. num, err := dORM.QueryTable("post").Filter("Tags__Tag__Name", "golang").All(&posts)
  819. throwFailNow(t, err)
  820. throwFailNow(t, AssertIs(num, 3))
  821. throwFailNow(t, AssertIs(posts[0].Title, "Introduction"))
  822. posts = []*Post{}
  823. num, err = dORM.QueryTable("post").Filter("Tags__Tag__Name", "golang").Filter("User__UserName", "slene").All(&posts)
  824. throwFailNow(t, err)
  825. throwFailNow(t, AssertIs(num, 1))
  826. throwFailNow(t, AssertIs(posts[0].Title, "Introduction"))
  827. posts = []*Post{}
  828. num, err = dORM.QueryTable("post").Filter("Tags__Tag__Name", "golang").
  829. Filter("User__UserName", "slene").RelatedSel().All(&posts)
  830. throwFailNow(t, err)
  831. throwFailNow(t, AssertIs(num, 1))
  832. throwFailNow(t, AssertIs(posts[0].User == nil, false))
  833. throwFailNow(t, AssertIs(posts[0].User.UserName, "slene"))
  834. var tags []*Tag
  835. num, err = dORM.QueryTable("tag").Filter("Posts__Post__Title", "Introduction").All(&tags)
  836. throwFailNow(t, err)
  837. throwFailNow(t, AssertIs(num, 1))
  838. throwFailNow(t, AssertIs(tags[0].Name, "golang"))
  839. tags = []*Tag{}
  840. num, err = dORM.QueryTable("tag").Filter("Posts__Post__Title", "Introduction").
  841. Filter("BestPost__User__UserName", "astaxie").All(&tags)
  842. throwFailNow(t, err)
  843. throwFailNow(t, AssertIs(num, 1))
  844. throwFailNow(t, AssertIs(tags[0].Name, "golang"))
  845. tags = []*Tag{}
  846. num, err = dORM.QueryTable("tag").Filter("Posts__Post__Title", "Introduction").
  847. Filter("BestPost__User__UserName", "astaxie").RelatedSel().All(&tags)
  848. throwFailNow(t, err)
  849. throwFailNow(t, AssertIs(num, 1))
  850. throwFailNow(t, AssertIs(tags[0].Name, "golang"))
  851. throwFailNow(t, AssertIs(tags[0].BestPost == nil, false))
  852. throwFailNow(t, AssertIs(tags[0].BestPost.Title, "Examples"))
  853. throwFailNow(t, AssertIs(tags[0].BestPost.User == nil, false))
  854. throwFailNow(t, AssertIs(tags[0].BestPost.User.UserName, "astaxie"))
  855. }
  856. func TestLoadRelated(t *testing.T) {
  857. // load reverse foreign key
  858. user := User{Id: 3}
  859. err := dORM.Read(&user)
  860. throwFailNow(t, err)
  861. num, err := dORM.LoadRelated(&user, "Posts")
  862. throwFailNow(t, err)
  863. throwFailNow(t, AssertIs(num, 2))
  864. throwFailNow(t, AssertIs(len(user.Posts), 2))
  865. throwFailNow(t, AssertIs(user.Posts[0].User.Id, 3))
  866. num, err = dORM.LoadRelated(&user, "Posts", true)
  867. throwFailNow(t, err)
  868. throwFailNow(t, AssertIs(len(user.Posts), 2))
  869. throwFailNow(t, AssertIs(user.Posts[0].User.UserName, "astaxie"))
  870. num, err = dORM.LoadRelated(&user, "Posts", true, 1)
  871. throwFailNow(t, err)
  872. throwFailNow(t, AssertIs(len(user.Posts), 1))
  873. num, err = dORM.LoadRelated(&user, "Posts", true, 0, 0, "-Id")
  874. throwFailNow(t, err)
  875. throwFailNow(t, AssertIs(len(user.Posts), 2))
  876. throwFailNow(t, AssertIs(user.Posts[0].Title, "Formatting"))
  877. num, err = dORM.LoadRelated(&user, "Posts", true, 1, 1, "Id")
  878. throwFailNow(t, err)
  879. throwFailNow(t, AssertIs(len(user.Posts), 1))
  880. throwFailNow(t, AssertIs(user.Posts[0].Title, "Formatting"))
  881. // load reverse one to one
  882. profile := Profile{Id: 3}
  883. profile.BestPost = &Post{Id: 2}
  884. num, err = dORM.Update(&profile, "BestPost")
  885. throwFailNow(t, err)
  886. throwFailNow(t, AssertIs(num, 1))
  887. err = dORM.Read(&profile)
  888. throwFailNow(t, err)
  889. num, err = dORM.LoadRelated(&profile, "User")
  890. throwFailNow(t, err)
  891. throwFailNow(t, AssertIs(num, 1))
  892. throwFailNow(t, AssertIs(profile.User == nil, false))
  893. throwFailNow(t, AssertIs(profile.User.UserName, "astaxie"))
  894. num, err = dORM.LoadRelated(&profile, "User", true)
  895. throwFailNow(t, err)
  896. throwFailNow(t, AssertIs(num, 1))
  897. throwFailNow(t, AssertIs(profile.User == nil, false))
  898. throwFailNow(t, AssertIs(profile.User.UserName, "astaxie"))
  899. throwFailNow(t, AssertIs(profile.User.Profile.Age, profile.Age))
  900. // load rel one to one
  901. err = dORM.Read(&user)
  902. throwFailNow(t, err)
  903. num, err = dORM.LoadRelated(&user, "Profile")
  904. throwFailNow(t, err)
  905. throwFailNow(t, AssertIs(num, 1))
  906. throwFailNow(t, AssertIs(user.Profile == nil, false))
  907. throwFailNow(t, AssertIs(user.Profile.Age, 30))
  908. num, err = dORM.LoadRelated(&user, "Profile", true)
  909. throwFailNow(t, err)
  910. throwFailNow(t, AssertIs(num, 1))
  911. throwFailNow(t, AssertIs(user.Profile == nil, false))
  912. throwFailNow(t, AssertIs(user.Profile.Age, 30))
  913. throwFailNow(t, AssertIs(user.Profile.BestPost == nil, false))
  914. throwFailNow(t, AssertIs(user.Profile.BestPost.Title, "Examples"))
  915. post := Post{Id: 2}
  916. // load rel foreign key
  917. err = dORM.Read(&post)
  918. throwFailNow(t, err)
  919. num, err = dORM.LoadRelated(&post, "User")
  920. throwFailNow(t, err)
  921. throwFailNow(t, AssertIs(num, 1))
  922. throwFailNow(t, AssertIs(post.User == nil, false))
  923. throwFailNow(t, AssertIs(post.User.UserName, "astaxie"))
  924. num, err = dORM.LoadRelated(&post, "User", true)
  925. throwFailNow(t, err)
  926. throwFailNow(t, AssertIs(num, 1))
  927. throwFailNow(t, AssertIs(post.User == nil, false))
  928. throwFailNow(t, AssertIs(post.User.UserName, "astaxie"))
  929. throwFailNow(t, AssertIs(post.User.Profile == nil, false))
  930. throwFailNow(t, AssertIs(post.User.Profile.Age, 30))
  931. // load rel m2m
  932. post = Post{Id: 2}
  933. err = dORM.Read(&post)
  934. throwFailNow(t, err)
  935. num, err = dORM.LoadRelated(&post, "Tags")
  936. throwFailNow(t, err)
  937. throwFailNow(t, AssertIs(num, 2))
  938. throwFailNow(t, AssertIs(len(post.Tags), 2))
  939. throwFailNow(t, AssertIs(post.Tags[0].Name, "golang"))
  940. num, err = dORM.LoadRelated(&post, "Tags", true)
  941. throwFailNow(t, err)
  942. throwFailNow(t, AssertIs(num, 2))
  943. throwFailNow(t, AssertIs(len(post.Tags), 2))
  944. throwFailNow(t, AssertIs(post.Tags[0].Name, "golang"))
  945. throwFailNow(t, AssertIs(post.Tags[0].BestPost == nil, false))
  946. throwFailNow(t, AssertIs(post.Tags[0].BestPost.User.UserName, "astaxie"))
  947. // load reverse m2m
  948. tag := Tag{Id: 1}
  949. err = dORM.Read(&tag)
  950. throwFailNow(t, err)
  951. num, err = dORM.LoadRelated(&tag, "Posts")
  952. throwFailNow(t, err)
  953. throwFailNow(t, AssertIs(num, 3))
  954. throwFailNow(t, AssertIs(tag.Posts[0].Title, "Introduction"))
  955. throwFailNow(t, AssertIs(tag.Posts[0].User.Id, 2))
  956. throwFailNow(t, AssertIs(tag.Posts[0].User.Profile == nil, true))
  957. num, err = dORM.LoadRelated(&tag, "Posts", true)
  958. throwFailNow(t, err)
  959. throwFailNow(t, AssertIs(num, 3))
  960. throwFailNow(t, AssertIs(tag.Posts[0].Title, "Introduction"))
  961. throwFailNow(t, AssertIs(tag.Posts[0].User.Id, 2))
  962. throwFailNow(t, AssertIs(tag.Posts[0].User.UserName, "slene"))
  963. }
  964. func TestQueryM2M(t *testing.T) {
  965. post := Post{Id: 4}
  966. m2m := dORM.QueryM2M(&post, "Tags")
  967. tag1 := []*Tag{&Tag{Name: "TestTag1"}, &Tag{Name: "TestTag2"}}
  968. tag2 := &Tag{Name: "TestTag3"}
  969. tag3 := []interface{}{&Tag{Name: "TestTag4"}}
  970. tags := []interface{}{tag1[0], tag1[1], tag2, tag3[0]}
  971. for _, tag := range tags {
  972. _, err := dORM.Insert(tag)
  973. throwFailNow(t, err)
  974. }
  975. num, err := m2m.Add(tag1)
  976. throwFailNow(t, err)
  977. throwFailNow(t, AssertIs(num, 2))
  978. num, err = m2m.Add(tag2)
  979. throwFailNow(t, err)
  980. throwFailNow(t, AssertIs(num, 1))
  981. num, err = m2m.Add(tag3)
  982. throwFailNow(t, err)
  983. throwFailNow(t, AssertIs(num, 1))
  984. num, err = m2m.Count()
  985. throwFailNow(t, err)
  986. throwFailNow(t, AssertIs(num, 5))
  987. num, err = m2m.Remove(tag3)
  988. throwFailNow(t, err)
  989. throwFailNow(t, AssertIs(num, 1))
  990. num, err = m2m.Count()
  991. throwFailNow(t, err)
  992. throwFailNow(t, AssertIs(num, 4))
  993. exist := m2m.Exist(tag2)
  994. throwFailNow(t, AssertIs(exist, true))
  995. num, err = m2m.Remove(tag2)
  996. throwFailNow(t, err)
  997. throwFailNow(t, AssertIs(num, 1))
  998. exist = m2m.Exist(tag2)
  999. throwFailNow(t, AssertIs(exist, false))
  1000. num, err = m2m.Count()
  1001. throwFailNow(t, err)
  1002. throwFailNow(t, AssertIs(num, 3))
  1003. num, err = m2m.Clear()
  1004. throwFailNow(t, err)
  1005. throwFailNow(t, AssertIs(num, 3))
  1006. num, err = m2m.Count()
  1007. throwFailNow(t, err)
  1008. throwFailNow(t, AssertIs(num, 0))
  1009. tag := Tag{Name: "test"}
  1010. _, err = dORM.Insert(&tag)
  1011. throwFailNow(t, err)
  1012. m2m = dORM.QueryM2M(&tag, "Posts")
  1013. post1 := []*Post{&Post{Title: "TestPost1"}, &Post{Title: "TestPost2"}}
  1014. post2 := &Post{Title: "TestPost3"}
  1015. post3 := []interface{}{&Post{Title: "TestPost4"}}
  1016. posts := []interface{}{post1[0], post1[1], post2, post3[0]}
  1017. for _, post := range posts {
  1018. p := post.(*Post)
  1019. p.User = &User{Id: 1}
  1020. _, err := dORM.Insert(post)
  1021. throwFailNow(t, err)
  1022. }
  1023. num, err = m2m.Add(post1)
  1024. throwFailNow(t, err)
  1025. throwFailNow(t, AssertIs(num, 2))
  1026. num, err = m2m.Add(post2)
  1027. throwFailNow(t, err)
  1028. throwFailNow(t, AssertIs(num, 1))
  1029. num, err = m2m.Add(post3)
  1030. throwFailNow(t, err)
  1031. throwFailNow(t, AssertIs(num, 1))
  1032. num, err = m2m.Count()
  1033. throwFailNow(t, err)
  1034. throwFailNow(t, AssertIs(num, 4))
  1035. num, err = m2m.Remove(post3)
  1036. throwFailNow(t, err)
  1037. throwFailNow(t, AssertIs(num, 1))
  1038. num, err = m2m.Count()
  1039. throwFailNow(t, err)
  1040. throwFailNow(t, AssertIs(num, 3))
  1041. exist = m2m.Exist(post2)
  1042. throwFailNow(t, AssertIs(exist, true))
  1043. num, err = m2m.Remove(post2)
  1044. throwFailNow(t, err)
  1045. throwFailNow(t, AssertIs(num, 1))
  1046. exist = m2m.Exist(post2)
  1047. throwFailNow(t, AssertIs(exist, false))
  1048. num, err = m2m.Count()
  1049. throwFailNow(t, err)
  1050. throwFailNow(t, AssertIs(num, 2))
  1051. num, err = m2m.Clear()
  1052. throwFailNow(t, err)
  1053. throwFailNow(t, AssertIs(num, 2))
  1054. num, err = m2m.Count()
  1055. throwFailNow(t, err)
  1056. throwFailNow(t, AssertIs(num, 0))
  1057. num, err = dORM.Delete(&tag)
  1058. throwFailNow(t, err)
  1059. throwFailNow(t, AssertIs(num, 1))
  1060. }
  1061. func TestQueryRelate(t *testing.T) {
  1062. // post := &Post{Id: 2}
  1063. // qs := dORM.QueryRelate(post, "Tags")
  1064. // num, err := qs.Count()
  1065. // throwFailNow(t, err)
  1066. // throwFailNow(t, AssertIs(num, 2))
  1067. // var tags []*Tag
  1068. // num, err = qs.All(&tags)
  1069. // throwFailNow(t, err)
  1070. // throwFailNow(t, AssertIs(num, 2))
  1071. // throwFailNow(t, AssertIs(tags[0].Name, "golang"))
  1072. // num, err = dORM.QueryTable("Tag").Filter("Posts__Post", 2).Count()
  1073. // throwFailNow(t, err)
  1074. // throwFailNow(t, AssertIs(num, 2))
  1075. }
  1076. func TestPrepareInsert(t *testing.T) {
  1077. qs := dORM.QueryTable("user")
  1078. i, err := qs.PrepareInsert()
  1079. throwFailNow(t, err)
  1080. var user User
  1081. user.UserName = "testing1"
  1082. num, err := i.Insert(&user)
  1083. throwFail(t, err)
  1084. throwFail(t, AssertIs(num > 0, true))
  1085. user.UserName = "testing2"
  1086. num, err = i.Insert(&user)
  1087. throwFail(t, err)
  1088. throwFail(t, AssertIs(num > 0, true))
  1089. num, err = qs.Filter("user_name__in", "testing1", "testing2").Delete()
  1090. throwFail(t, err)
  1091. throwFail(t, AssertIs(num, 2))
  1092. err = i.Close()
  1093. throwFail(t, err)
  1094. err = i.Close()
  1095. throwFail(t, AssertIs(err, ErrStmtClosed))
  1096. }
  1097. func TestRawExec(t *testing.T) {
  1098. Q := dDbBaser.TableQuote()
  1099. query := fmt.Sprintf("UPDATE %suser%s SET %suser_name%s = ? WHERE %suser_name%s = ?", Q, Q, Q, Q, Q, Q)
  1100. res, err := dORM.Raw(query, "testing", "slene").Exec()
  1101. throwFail(t, err)
  1102. num, err := res.RowsAffected()
  1103. throwFail(t, AssertIs(num, 1), err)
  1104. res, err = dORM.Raw(query, "slene", "testing").Exec()
  1105. throwFail(t, err)
  1106. num, err = res.RowsAffected()
  1107. throwFail(t, AssertIs(num, 1), err)
  1108. }
  1109. func TestRawQueryRow(t *testing.T) {
  1110. var (
  1111. Boolean bool
  1112. Char string
  1113. Text string
  1114. Date time.Time
  1115. DateTime time.Time
  1116. Byte byte
  1117. Rune rune
  1118. Int int
  1119. Int8 int
  1120. Int16 int16
  1121. Int32 int32
  1122. Int64 int64
  1123. Uint uint
  1124. Uint8 uint8
  1125. Uint16 uint16
  1126. Uint32 uint32
  1127. Uint64 uint64
  1128. Float32 float32
  1129. Float64 float64
  1130. Decimal float64
  1131. )
  1132. data_values := make(map[string]interface{}, len(Data_Values))
  1133. for k, v := range Data_Values {
  1134. data_values[strings.ToLower(k)] = v
  1135. }
  1136. Q := dDbBaser.TableQuote()
  1137. cols := []string{
  1138. "id", "boolean", "char", "text", "date", "datetime", "byte", "rune", "int", "int8", "int16", "int32",
  1139. "int64", "uint", "uint8", "uint16", "uint32", "uint64", "float32", "float64", "decimal",
  1140. }
  1141. sep := fmt.Sprintf("%s, %s", Q, Q)
  1142. query := fmt.Sprintf("SELECT %s%s%s FROM data WHERE id = ?", Q, strings.Join(cols, sep), Q)
  1143. var id int
  1144. values := []interface{}{
  1145. &id, &Boolean, &Char, &Text, &Date, &DateTime, &Byte, &Rune, &Int, &Int8, &Int16, &Int32,
  1146. &Int64, &Uint, &Uint8, &Uint16, &Uint32, &Uint64, &Float32, &Float64, &Decimal,
  1147. }
  1148. err := dORM.Raw(query, 1).QueryRow(values...)
  1149. throwFailNow(t, err)
  1150. for i, col := range cols {
  1151. vu := values[i]
  1152. v := reflect.ValueOf(vu).Elem().Interface()
  1153. switch col {
  1154. case "id":
  1155. throwFail(t, AssertIs(id, 1))
  1156. case "date":
  1157. v = v.(time.Time).In(DefaultTimeLoc)
  1158. value := data_values[col].(time.Time).In(DefaultTimeLoc)
  1159. throwFail(t, AssertIs(v, value, test_Date))
  1160. case "datetime":
  1161. v = v.(time.Time).In(DefaultTimeLoc)
  1162. value := data_values[col].(time.Time).In(DefaultTimeLoc)
  1163. throwFail(t, AssertIs(v, value, test_DateTime))
  1164. default:
  1165. throwFail(t, AssertIs(v, data_values[col]))
  1166. }
  1167. }
  1168. var (
  1169. uid int
  1170. status *int
  1171. pid *int
  1172. )
  1173. cols = []string{
  1174. "id", "Status", "profile_id",
  1175. }
  1176. query = fmt.Sprintf("SELECT %s%s%s FROM %suser%s WHERE id = ?", Q, strings.Join(cols, sep), Q, Q, Q)
  1177. err = dORM.Raw(query, 4).QueryRow(&uid, &status, &pid)
  1178. throwFail(t, err)
  1179. throwFail(t, AssertIs(uid, 4))
  1180. throwFail(t, AssertIs(*status, 3))
  1181. throwFail(t, AssertIs(pid, nil))
  1182. }
  1183. func TestQueryRows(t *testing.T) {
  1184. Q := dDbBaser.TableQuote()
  1185. var datas []*Data
  1186. query := fmt.Sprintf("SELECT * FROM %sdata%s", Q, Q)
  1187. num, err := dORM.Raw(query).QueryRows(&datas)
  1188. throwFailNow(t, err)
  1189. throwFailNow(t, AssertIs(num, 1))
  1190. throwFailNow(t, AssertIs(len(datas), 1))
  1191. ind := reflect.Indirect(reflect.ValueOf(datas[0]))
  1192. for name, value := range Data_Values {
  1193. e := ind.FieldByName(name)
  1194. vu := e.Interface()
  1195. switch name {
  1196. case "Date":
  1197. vu = vu.(time.Time).In(DefaultTimeLoc).Format(test_Date)
  1198. value = value.(time.Time).In(DefaultTimeLoc).Format(test_Date)
  1199. case "DateTime":
  1200. vu = vu.(time.Time).In(DefaultTimeLoc).Format(test_DateTime)
  1201. value = value.(time.Time).In(DefaultTimeLoc).Format(test_DateTime)
  1202. }
  1203. throwFail(t, AssertIs(vu == value, true), value, vu)
  1204. }
  1205. var datas2 []Data
  1206. query = fmt.Sprintf("SELECT * FROM %sdata%s", Q, Q)
  1207. num, err = dORM.Raw(query).QueryRows(&datas2)
  1208. throwFailNow(t, err)
  1209. throwFailNow(t, AssertIs(num, 1))
  1210. throwFailNow(t, AssertIs(len(datas2), 1))
  1211. ind = reflect.Indirect(reflect.ValueOf(datas2[0]))
  1212. for name, value := range Data_Values {
  1213. e := ind.FieldByName(name)
  1214. vu := e.Interface()
  1215. switch name {
  1216. case "Date":
  1217. vu = vu.(time.Time).In(DefaultTimeLoc).Format(test_Date)
  1218. value = value.(time.Time).In(DefaultTimeLoc).Format(test_Date)
  1219. case "DateTime":
  1220. vu = vu.(time.Time).In(DefaultTimeLoc).Format(test_DateTime)
  1221. value = value.(time.Time).In(DefaultTimeLoc).Format(test_DateTime)
  1222. }
  1223. throwFail(t, AssertIs(vu == value, true), value, vu)
  1224. }
  1225. var ids []int
  1226. var usernames []string
  1227. query = fmt.Sprintf("SELECT %sid%s, %suser_name%s FROM %suser%s ORDER BY %sid%s ASC", Q, Q, Q, Q, Q, Q, Q, Q)
  1228. num, err = dORM.Raw(query).QueryRows(&ids, &usernames)
  1229. throwFailNow(t, err)
  1230. throwFailNow(t, AssertIs(num, 3))
  1231. throwFailNow(t, AssertIs(len(ids), 3))
  1232. throwFailNow(t, AssertIs(ids[0], 2))
  1233. throwFailNow(t, AssertIs(usernames[0], "slene"))
  1234. throwFailNow(t, AssertIs(ids[1], 3))
  1235. throwFailNow(t, AssertIs(usernames[1], "astaxie"))
  1236. throwFailNow(t, AssertIs(ids[2], 4))
  1237. throwFailNow(t, AssertIs(usernames[2], "nobody"))
  1238. }
  1239. func TestRawValues(t *testing.T) {
  1240. Q := dDbBaser.TableQuote()
  1241. var maps []Params
  1242. query := fmt.Sprintf("SELECT %suser_name%s FROM %suser%s WHERE %sStatus%s = ?", Q, Q, Q, Q, Q, Q)
  1243. num, err := dORM.Raw(query, 1).Values(&maps)
  1244. throwFail(t, err)
  1245. throwFail(t, AssertIs(num, 1))
  1246. if num == 1 {
  1247. throwFail(t, AssertIs(maps[0]["user_name"], "slene"))
  1248. }
  1249. var lists []ParamsList
  1250. num, err = dORM.Raw(query, 1).ValuesList(&lists)
  1251. throwFail(t, err)
  1252. throwFail(t, AssertIs(num, 1))
  1253. if num == 1 {
  1254. throwFail(t, AssertIs(lists[0][0], "slene"))
  1255. }
  1256. query = fmt.Sprintf("SELECT %sprofile_id%s FROM %suser%s ORDER BY %sid%s ASC", Q, Q, Q, Q, Q, Q)
  1257. var list ParamsList
  1258. num, err = dORM.Raw(query).ValuesFlat(&list)
  1259. throwFail(t, err)
  1260. throwFail(t, AssertIs(num, 3))
  1261. if num == 3 {
  1262. throwFail(t, AssertIs(list[0], "2"))
  1263. throwFail(t, AssertIs(list[1], "3"))
  1264. throwFail(t, AssertIs(list[2], nil))
  1265. }
  1266. }
  1267. func TestRawPrepare(t *testing.T) {
  1268. switch {
  1269. case IsMysql || IsSqlite:
  1270. pre, err := dORM.Raw("INSERT INTO tag (name) VALUES (?)").Prepare()
  1271. throwFail(t, err)
  1272. if pre != nil {
  1273. r, err := pre.Exec("name1")
  1274. throwFail(t, err)
  1275. tid, err := r.LastInsertId()
  1276. throwFail(t, err)
  1277. throwFail(t, AssertIs(tid > 0, true))
  1278. r, err = pre.Exec("name2")
  1279. throwFail(t, err)
  1280. id, err := r.LastInsertId()
  1281. throwFail(t, err)
  1282. throwFail(t, AssertIs(id, tid+1))
  1283. r, err = pre.Exec("name3")
  1284. throwFail(t, err)
  1285. id, err = r.LastInsertId()
  1286. throwFail(t, err)
  1287. throwFail(t, AssertIs(id, tid+2))
  1288. err = pre.Close()
  1289. throwFail(t, err)
  1290. res, err := dORM.Raw("DELETE FROM tag WHERE name IN (?, ?, ?)", []string{"name1", "name2", "name3"}).Exec()
  1291. throwFail(t, err)
  1292. num, err := res.RowsAffected()
  1293. throwFail(t, err)
  1294. throwFail(t, AssertIs(num, 3))
  1295. }
  1296. case IsPostgres:
  1297. pre, err := dORM.Raw(`INSERT INTO "tag" ("name") VALUES (?) RETURNING "id"`).Prepare()
  1298. throwFail(t, err)
  1299. if pre != nil {
  1300. _, err := pre.Exec("name1")
  1301. throwFail(t, err)
  1302. _, err = pre.Exec("name2")
  1303. throwFail(t, err)
  1304. _, err = pre.Exec("name3")
  1305. throwFail(t, err)
  1306. err = pre.Close()
  1307. throwFail(t, err)
  1308. res, err := dORM.Raw(`DELETE FROM "tag" WHERE "name" IN (?, ?, ?)`, []string{"name1", "name2", "name3"}).Exec()
  1309. throwFail(t, err)
  1310. if err == nil {
  1311. num, err := res.RowsAffected()
  1312. throwFail(t, err)
  1313. throwFail(t, AssertIs(num, 3))
  1314. }
  1315. }
  1316. }
  1317. }
  1318. func TestUpdate(t *testing.T) {
  1319. qs := dORM.QueryTable("user")
  1320. num, err := qs.Filter("user_name", "slene").Filter("is_staff", false).Update(Params{
  1321. "is_staff": true,
  1322. "is_active": true,
  1323. })
  1324. throwFail(t, err)
  1325. throwFail(t, AssertIs(num, 1))
  1326. // with join
  1327. num, err = qs.Filter("user_name", "slene").Filter("profile__age", 28).Filter("is_staff", true).Update(Params{
  1328. "is_staff": false,
  1329. })
  1330. throwFail(t, err)
  1331. throwFail(t, AssertIs(num, 1))
  1332. num, err = qs.Filter("user_name", "slene").Update(Params{
  1333. "Nums": ColValue(Col_Add, 100),
  1334. })
  1335. throwFail(t, err)
  1336. throwFail(t, AssertIs(num, 1))
  1337. num, err = qs.Filter("user_name", "slene").Update(Params{
  1338. "Nums": ColValue(Col_Minus, 50),
  1339. })
  1340. throwFail(t, err)
  1341. throwFail(t, AssertIs(num, 1))
  1342. num, err = qs.Filter("user_name", "slene").Update(Params{
  1343. "Nums": ColValue(Col_Multiply, 3),
  1344. })
  1345. throwFail(t, err)
  1346. throwFail(t, AssertIs(num, 1))
  1347. num, err = qs.Filter("user_name", "slene").Update(Params{
  1348. "Nums": ColValue(Col_Except, 5),
  1349. })
  1350. throwFail(t, err)
  1351. throwFail(t, AssertIs(num, 1))
  1352. user := User{UserName: "slene"}
  1353. err = dORM.Read(&user, "UserName")
  1354. throwFail(t, err)
  1355. throwFail(t, AssertIs(user.Nums, 30))
  1356. }
  1357. func TestDelete(t *testing.T) {
  1358. qs := dORM.QueryTable("user_profile")
  1359. num, err := qs.Filter("user__user_name", "slene").Delete()
  1360. throwFail(t, err)
  1361. throwFail(t, AssertIs(num, 1))
  1362. qs = dORM.QueryTable("user")
  1363. num, err = qs.Filter("user_name", "slene").Filter("profile__isnull", true).Count()
  1364. throwFail(t, err)
  1365. throwFail(t, AssertIs(num, 1))
  1366. qs = dORM.QueryTable("comment")
  1367. num, err = qs.Count()
  1368. throwFail(t, err)
  1369. throwFail(t, AssertIs(num, 6))
  1370. qs = dORM.QueryTable("post")
  1371. num, err = qs.Filter("Id", 3).Delete()
  1372. throwFail(t, err)
  1373. throwFail(t, AssertIs(num, 1))
  1374. qs = dORM.QueryTable("comment")
  1375. num, err = qs.Count()
  1376. throwFail(t, err)
  1377. throwFail(t, AssertIs(num, 4))
  1378. qs = dORM.QueryTable("comment")
  1379. num, err = qs.Filter("Post__User", 3).Delete()
  1380. throwFail(t, err)
  1381. throwFail(t, AssertIs(num, 3))
  1382. qs = dORM.QueryTable("comment")
  1383. num, err = qs.Count()
  1384. throwFail(t, err)
  1385. throwFail(t, AssertIs(num, 1))
  1386. }
  1387. func TestTransaction(t *testing.T) {
  1388. // this test worked when database support transaction
  1389. o := NewOrm()
  1390. err := o.Begin()
  1391. throwFail(t, err)
  1392. var names = []string{"1", "2", "3"}
  1393. var tag Tag
  1394. tag.Name = names[0]
  1395. id, err := o.Insert(&tag)
  1396. throwFail(t, err)
  1397. throwFail(t, AssertIs(id > 0, true))
  1398. num, err := o.QueryTable("tag").Filter("name", "golang").Update(Params{"name": names[1]})
  1399. throwFail(t, err)
  1400. throwFail(t, AssertIs(num, 1))
  1401. switch {
  1402. case IsMysql || IsSqlite:
  1403. res, err := o.Raw("INSERT INTO tag (name) VALUES (?)", names[2]).Exec()
  1404. throwFail(t, err)
  1405. if err == nil {
  1406. id, err = res.LastInsertId()
  1407. throwFail(t, err)
  1408. throwFail(t, AssertIs(id > 0, true))
  1409. }
  1410. }
  1411. err = o.Rollback()
  1412. throwFail(t, err)
  1413. num, err = o.QueryTable("tag").Filter("name__in", names).Count()
  1414. throwFail(t, err)
  1415. throwFail(t, AssertIs(num, 0))
  1416. err = o.Begin()
  1417. throwFail(t, err)
  1418. tag.Name = "commit"
  1419. id, err = o.Insert(&tag)
  1420. throwFail(t, err)
  1421. throwFail(t, AssertIs(id > 0, true))
  1422. o.Commit()
  1423. throwFail(t, err)
  1424. num, err = o.QueryTable("tag").Filter("name", "commit").Delete()
  1425. throwFail(t, err)
  1426. throwFail(t, AssertIs(num, 1))
  1427. }
  1428. func TestReadOrCreate(t *testing.T) {
  1429. u := &User{
  1430. UserName: "Kyle",
  1431. Email: "kylemcc@gmail.com",
  1432. Password: "other_pass",
  1433. Status: 7,
  1434. IsStaff: false,
  1435. IsActive: true,
  1436. }
  1437. created, pk, err := dORM.ReadOrCreate(u, "UserName")
  1438. throwFail(t, err)
  1439. throwFail(t, AssertIs(created, true))
  1440. throwFail(t, AssertIs(u.UserName, "Kyle"))
  1441. throwFail(t, AssertIs(u.Email, "kylemcc@gmail.com"))
  1442. throwFail(t, AssertIs(u.Password, "other_pass"))
  1443. throwFail(t, AssertIs(u.Status, 7))
  1444. throwFail(t, AssertIs(u.IsStaff, false))
  1445. throwFail(t, AssertIs(u.IsActive, true))
  1446. throwFail(t, AssertIs(u.Created.In(DefaultTimeLoc), u.Created.In(DefaultTimeLoc), test_Date))
  1447. throwFail(t, AssertIs(u.Updated.In(DefaultTimeLoc), u.Updated.In(DefaultTimeLoc), test_DateTime))
  1448. nu := &User{UserName: u.UserName, Email: "someotheremail@gmail.com"}
  1449. created, pk, err = dORM.ReadOrCreate(nu, "UserName")
  1450. throwFail(t, err)
  1451. throwFail(t, AssertIs(created, false))
  1452. throwFail(t, AssertIs(nu.Id, u.Id))
  1453. throwFail(t, AssertIs(pk, u.Id))
  1454. throwFail(t, AssertIs(nu.UserName, u.UserName))
  1455. throwFail(t, AssertIs(nu.Email, u.Email)) // should contain the value in the table, not the one specified above
  1456. throwFail(t, AssertIs(nu.Password, u.Password))
  1457. throwFail(t, AssertIs(nu.Status, u.Status))
  1458. throwFail(t, AssertIs(nu.IsStaff, u.IsStaff))
  1459. throwFail(t, AssertIs(nu.IsActive, u.IsActive))
  1460. dORM.Delete(u)
  1461. }