call transaction Dao events only after commit, added totalPages to the search response and updated the tests
This commit is contained in:
		
							parent
							
								
									8288da8372
								
							
						
					
					
						commit
						f8f785d6e3
					
				| 
						 | 
					@ -553,7 +553,7 @@ func TestCollectionImport(t *testing.T) {
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name:   "authorized as admin + successfull collections save",
 | 
								Name:   "authorized as admin + successful collections save",
 | 
				
			||||||
			Method: http.MethodPut,
 | 
								Method: http.MethodPut,
 | 
				
			||||||
			Url:    "/api/collections/import",
 | 
								Url:    "/api/collections/import",
 | 
				
			||||||
			Body: strings.NewReader(`{
 | 
								Body: strings.NewReader(`{
 | 
				
			||||||
| 
						 | 
					@ -601,7 +601,7 @@ func TestCollectionImport(t *testing.T) {
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name:   "authorized as admin + successfull collections save and old non-system collections deletion",
 | 
								Name:   "authorized as admin + successful collections save and old non-system collections deletion",
 | 
				
			||||||
			Method: http.MethodPut,
 | 
								Method: http.MethodPut,
 | 
				
			||||||
			Url:    "/api/collections/import",
 | 
								Url:    "/api/collections/import",
 | 
				
			||||||
			Body: strings.NewReader(`{
 | 
								Body: strings.NewReader(`{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -210,13 +210,17 @@ func (api *realtimeApi) bindEvents() {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	api.app.OnRecordAfterCreateRequest().Add(func(e *core.RecordCreateEvent) error {
 | 
						api.app.OnModelAfterCreate().Add(func(e *core.ModelEvent) error {
 | 
				
			||||||
		api.broadcastRecord("create", e.Record)
 | 
							if record, ok := e.Model.(*models.Record); ok {
 | 
				
			||||||
 | 
								api.broadcastRecord("create", record)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	api.app.OnRecordAfterUpdateRequest().Add(func(e *core.RecordUpdateEvent) error {
 | 
						api.app.OnModelAfterUpdate().Add(func(e *core.ModelEvent) error {
 | 
				
			||||||
		api.broadcastRecord("update", e.Record)
 | 
							if record, ok := e.Model.(*models.Record); ok {
 | 
				
			||||||
 | 
								api.broadcastRecord("update", record)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -217,7 +217,7 @@ func init() {
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func migrateCollectionsHandler(app core.App, args []string) error {
 | 
					func migrateCollectionsHandler(app core.App, args []string) error {
 | 
				
			||||||
	createArgs := []string{"collections_import"}
 | 
						createArgs := []string{"collections_snapshot"}
 | 
				
			||||||
	createArgs = append(createArgs, args...)
 | 
						createArgs = append(createArgs, args...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dao := daos.New(app.DB())
 | 
						dao := daos.New(app.DB())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										26
									
								
								daos/base.go
								
								
								
								
							
							
						
						
									
										26
									
								
								daos/base.go
								
								
								
								
							| 
						 | 
					@ -65,12 +65,11 @@ func (dao *Dao) RunInTransaction(fn func(txDao *Dao) error) error {
 | 
				
			||||||
		// so execute the function within the current transaction
 | 
							// so execute the function within the current transaction
 | 
				
			||||||
		return fn(dao)
 | 
							return fn(dao)
 | 
				
			||||||
	case *dbx.DB:
 | 
						case *dbx.DB:
 | 
				
			||||||
 | 
					 | 
				
			||||||
		return txOrDB.Transactional(func(tx *dbx.Tx) error {
 | 
					 | 
				
			||||||
			txDao := New(tx)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		afterCalls := []afterCallGroup{}
 | 
							afterCalls := []afterCallGroup{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							txError := txOrDB.Transactional(func(tx *dbx.Tx) error {
 | 
				
			||||||
 | 
								txDao := New(tx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if dao.BeforeCreateFunc != nil {
 | 
								if dao.BeforeCreateFunc != nil {
 | 
				
			||||||
				txDao.BeforeCreateFunc = func(eventDao *Dao, m models.Model) error {
 | 
									txDao.BeforeCreateFunc = func(eventDao *Dao, m models.Model) error {
 | 
				
			||||||
					return dao.BeforeCreateFunc(eventDao, m)
 | 
										return dao.BeforeCreateFunc(eventDao, m)
 | 
				
			||||||
| 
						 | 
					@ -103,23 +102,24 @@ func (dao *Dao) RunInTransaction(fn func(txDao *Dao) error) error {
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := fn(txDao); err != nil {
 | 
								return fn(txDao)
 | 
				
			||||||
				return err
 | 
							})
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// execute after event calls on successfull transaction
 | 
							if txError == nil {
 | 
				
			||||||
 | 
								// execute after event calls on successful transaction
 | 
				
			||||||
			for _, call := range afterCalls {
 | 
								for _, call := range afterCalls {
 | 
				
			||||||
				if call.Action == "create" {
 | 
									switch call.Action {
 | 
				
			||||||
 | 
									case "create":
 | 
				
			||||||
					dao.AfterCreateFunc(call.EventDao, call.Model)
 | 
										dao.AfterCreateFunc(call.EventDao, call.Model)
 | 
				
			||||||
				} else if call.Action == "update" {
 | 
									case "update":
 | 
				
			||||||
					dao.AfterUpdateFunc(call.EventDao, call.Model)
 | 
										dao.AfterUpdateFunc(call.EventDao, call.Model)
 | 
				
			||||||
				} else if call.Action == "delete" {
 | 
									case "delete":
 | 
				
			||||||
					dao.AfterDeleteFunc(call.EventDao, call.Model)
 | 
										dao.AfterDeleteFunc(call.EventDao, call.Model)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return nil
 | 
							return txError
 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return errors.New("Failed to start transaction (unknown dao.db)")
 | 
						return errors.New("Failed to start transaction (unknown dao.db)")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -365,33 +365,35 @@ func TestDaoTransactionHooksCallsOnFailure(t *testing.T) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	existingModel, _ := testApp.Dao().FindAdminByEmail("test@example.com")
 | 
						existingModel, _ := testApp.Dao().FindAdminByEmail("test@example.com")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	baseDao.RunInTransaction(func(txDao *daos.Dao) error {
 | 
						baseDao.RunInTransaction(func(txDao1 *daos.Dao) error {
 | 
				
			||||||
 | 
							return txDao1.RunInTransaction(func(txDao2 *daos.Dao) error {
 | 
				
			||||||
			// test create
 | 
								// test create
 | 
				
			||||||
			// ---
 | 
								// ---
 | 
				
			||||||
			newModel := &models.Admin{}
 | 
								newModel := &models.Admin{}
 | 
				
			||||||
			newModel.Email = "test_new1@example.com"
 | 
								newModel.Email = "test_new1@example.com"
 | 
				
			||||||
			newModel.SetPassword("123456")
 | 
								newModel.SetPassword("123456")
 | 
				
			||||||
		if err := txDao.Save(newModel); err != nil {
 | 
								if err := txDao2.Save(newModel); err != nil {
 | 
				
			||||||
				t.Fatal(err)
 | 
									t.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// test update (twice)
 | 
								// test update (twice)
 | 
				
			||||||
			// ---
 | 
								// ---
 | 
				
			||||||
		if err := txDao.Save(existingModel); err != nil {
 | 
								if err := txDao2.Save(existingModel); err != nil {
 | 
				
			||||||
				t.Fatal(err)
 | 
									t.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		if err := txDao.Save(existingModel); err != nil {
 | 
								if err := txDao2.Save(existingModel); err != nil {
 | 
				
			||||||
				t.Fatal(err)
 | 
									t.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// test delete
 | 
								// test delete
 | 
				
			||||||
			// ---
 | 
								// ---
 | 
				
			||||||
		if err := txDao.Delete(existingModel); err != nil {
 | 
								if err := txDao2.Delete(existingModel); err != nil {
 | 
				
			||||||
				t.Fatal(err)
 | 
									t.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return errors.New("test_tx_error")
 | 
								return errors.New("test_tx_error")
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if beforeCreateFuncCalls != 1 {
 | 
						if beforeCreateFuncCalls != 1 {
 | 
				
			||||||
		t.Fatalf("Expected beforeCreateFuncCalls to be called 1 times, got %d", beforeCreateFuncCalls)
 | 
							t.Fatalf("Expected beforeCreateFuncCalls to be called 1 times, got %d", beforeCreateFuncCalls)
 | 
				
			||||||
| 
						 | 
					@ -451,33 +453,35 @@ func TestDaoTransactionHooksCallsOnSuccess(t *testing.T) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	existingModel, _ := testApp.Dao().FindAdminByEmail("test@example.com")
 | 
						existingModel, _ := testApp.Dao().FindAdminByEmail("test@example.com")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	baseDao.RunInTransaction(func(txDao *daos.Dao) error {
 | 
						baseDao.RunInTransaction(func(txDao1 *daos.Dao) error {
 | 
				
			||||||
 | 
							return txDao1.RunInTransaction(func(txDao2 *daos.Dao) error {
 | 
				
			||||||
			// test create
 | 
								// test create
 | 
				
			||||||
			// ---
 | 
								// ---
 | 
				
			||||||
			newModel := &models.Admin{}
 | 
								newModel := &models.Admin{}
 | 
				
			||||||
			newModel.Email = "test_new1@example.com"
 | 
								newModel.Email = "test_new1@example.com"
 | 
				
			||||||
			newModel.SetPassword("123456")
 | 
								newModel.SetPassword("123456")
 | 
				
			||||||
		if err := txDao.Save(newModel); err != nil {
 | 
								if err := txDao2.Save(newModel); err != nil {
 | 
				
			||||||
				t.Fatal(err)
 | 
									t.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// test update (twice)
 | 
								// test update (twice)
 | 
				
			||||||
			// ---
 | 
								// ---
 | 
				
			||||||
		if err := txDao.Save(existingModel); err != nil {
 | 
								if err := txDao2.Save(existingModel); err != nil {
 | 
				
			||||||
				t.Fatal(err)
 | 
									t.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		if err := txDao.Save(existingModel); err != nil {
 | 
								if err := txDao2.Save(existingModel); err != nil {
 | 
				
			||||||
				t.Fatal(err)
 | 
									t.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// test delete
 | 
								// test delete
 | 
				
			||||||
			// ---
 | 
								// ---
 | 
				
			||||||
		if err := txDao.Delete(existingModel); err != nil {
 | 
								if err := txDao2.Delete(existingModel); err != nil {
 | 
				
			||||||
				t.Fatal(err)
 | 
									t.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return nil
 | 
								return nil
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if beforeCreateFuncCalls != 1 {
 | 
						if beforeCreateFuncCalls != 1 {
 | 
				
			||||||
		t.Fatalf("Expected beforeCreateFuncCalls to be called 1 times, got %d", beforeCreateFuncCalls)
 | 
							t.Fatalf("Expected beforeCreateFuncCalls to be called 1 times, got %d", beforeCreateFuncCalls)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -298,7 +298,6 @@ func TestFindUserRelatedRecords(t *testing.T) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if len(records) != len(scenario.expectedIds) {
 | 
							if len(records) != len(scenario.expectedIds) {
 | 
				
			||||||
			fmt.Println(records[0])
 | 
					 | 
				
			||||||
			t.Errorf("(%d) Expected %d records, got %d (%v)", i, len(scenario.expectedIds), len(records), records)
 | 
								t.Errorf("(%d) Expected %d records, got %d (%v)", i, len(scenario.expectedIds), len(records), records)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,6 @@ func NewRunner(db *dbx.DB, migrationsList MigrationsList) (*Runner, error) {
 | 
				
			||||||
// The following commands are supported:
 | 
					// The following commands are supported:
 | 
				
			||||||
// - up       - applies all migrations
 | 
					// - up       - applies all migrations
 | 
				
			||||||
// - down [n] - reverts the last n applied migrations
 | 
					// - down [n] - reverts the last n applied migrations
 | 
				
			||||||
// - create NEW_MIGRATION_NAME - create NEW_MIGRATION_NAME.go file from a migration template
 | 
					 | 
				
			||||||
func (r *Runner) Run(args ...string) error {
 | 
					func (r *Runner) Run(args ...string) error {
 | 
				
			||||||
	cmd := "up"
 | 
						cmd := "up"
 | 
				
			||||||
	if len(args) > 0 {
 | 
						if len(args) > 0 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,7 @@ type Result struct {
 | 
				
			||||||
	Page       int `json:"page"`
 | 
						Page       int `json:"page"`
 | 
				
			||||||
	PerPage    int `json:"perPage"`
 | 
						PerPage    int `json:"perPage"`
 | 
				
			||||||
	TotalItems int `json:"totalItems"`
 | 
						TotalItems int `json:"totalItems"`
 | 
				
			||||||
 | 
						TotalPages int `json:"totalPages"`
 | 
				
			||||||
	Items      any `json:"items"`
 | 
						Items      any `json:"items"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -213,10 +214,12 @@ func (s *Provider) Exec(items any) (*Result, error) {
 | 
				
			||||||
		s.perPage = MaxPerPage
 | 
							s.perPage = MaxPerPage
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						totalPages := int(math.Ceil(float64(totalCount) / float64(s.perPage)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// normalize page according to the total count
 | 
						// normalize page according to the total count
 | 
				
			||||||
	if s.page <= 0 || totalCount == 0 {
 | 
						if s.page <= 0 || totalCount == 0 {
 | 
				
			||||||
		s.page = 1
 | 
							s.page = 1
 | 
				
			||||||
	} else if totalPages := int(math.Ceil(float64(totalCount) / float64(s.perPage))); s.page > totalPages {
 | 
						} else if s.page > totalPages {
 | 
				
			||||||
		s.page = totalPages
 | 
							s.page = totalPages
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -233,6 +236,7 @@ func (s *Provider) Exec(items any) (*Result, error) {
 | 
				
			||||||
		Page:       s.page,
 | 
							Page:       s.page,
 | 
				
			||||||
		PerPage:    s.perPage,
 | 
							PerPage:    s.perPage,
 | 
				
			||||||
		TotalItems: int(totalCount),
 | 
							TotalItems: int(totalCount),
 | 
				
			||||||
 | 
							TotalPages: totalPages,
 | 
				
			||||||
		Items:      items,
 | 
							Items:      items,
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -236,7 +236,7 @@ func TestProviderExecNonEmptyQuery(t *testing.T) {
 | 
				
			||||||
			[]FilterData{},
 | 
								[]FilterData{},
 | 
				
			||||||
			"",
 | 
								"",
 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
			`{"page":1,"perPage":10,"totalItems":2,"items":[{"test1":1,"test2":"test2.1","test3":""},{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
								`{"page":1,"perPage":10,"totalItems":2,"totalPages":1,"items":[{"test1":1,"test2":"test2.1","test3":""},{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
				
			||||||
			[]string{
 | 
								[]string{
 | 
				
			||||||
				"SELECT COUNT(*) FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC",
 | 
									"SELECT COUNT(*) FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC",
 | 
				
			||||||
				"SELECT * FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC LIMIT 10",
 | 
									"SELECT * FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC LIMIT 10",
 | 
				
			||||||
| 
						 | 
					@ -250,7 +250,7 @@ func TestProviderExecNonEmptyQuery(t *testing.T) {
 | 
				
			||||||
			[]FilterData{},
 | 
								[]FilterData{},
 | 
				
			||||||
			"",
 | 
								"",
 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
			`{"page":1,"perPage":30,"totalItems":2,"items":[{"test1":1,"test2":"test2.1","test3":""},{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
								`{"page":1,"perPage":30,"totalItems":2,"totalPages":1,"items":[{"test1":1,"test2":"test2.1","test3":""},{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
				
			||||||
			[]string{
 | 
								[]string{
 | 
				
			||||||
				"SELECT COUNT(*) FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC",
 | 
									"SELECT COUNT(*) FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC",
 | 
				
			||||||
				"SELECT * FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC LIMIT 30",
 | 
									"SELECT * FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC LIMIT 30",
 | 
				
			||||||
| 
						 | 
					@ -286,7 +286,7 @@ func TestProviderExecNonEmptyQuery(t *testing.T) {
 | 
				
			||||||
			[]FilterData{"test2 != null", "test1 >= 2"},
 | 
								[]FilterData{"test2 != null", "test1 >= 2"},
 | 
				
			||||||
			"",
 | 
								"",
 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
			`{"page":1,"perPage":` + fmt.Sprint(MaxPerPage) + `,"totalItems":1,"items":[{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
								`{"page":1,"perPage":` + fmt.Sprint(MaxPerPage) + `,"totalItems":1,"totalPages":1,"items":[{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
				
			||||||
			[]string{
 | 
								[]string{
 | 
				
			||||||
				"SELECT COUNT(*) FROM `test` WHERE ((NOT (`test1` IS NULL)) AND (COALESCE(test2, '') != COALESCE(null, ''))) AND (test1 >= 2) ORDER BY `test1` ASC, `test2` DESC",
 | 
									"SELECT COUNT(*) FROM `test` WHERE ((NOT (`test1` IS NULL)) AND (COALESCE(test2, '') != COALESCE(null, ''))) AND (test1 >= 2) ORDER BY `test1` ASC, `test2` DESC",
 | 
				
			||||||
				"SELECT * FROM `test` WHERE ((NOT (`test1` IS NULL)) AND (COALESCE(test2, '') != COALESCE(null, ''))) AND (test1 >= 2) ORDER BY `test1` ASC, `test2` DESC LIMIT 200",
 | 
									"SELECT * FROM `test` WHERE ((NOT (`test1` IS NULL)) AND (COALESCE(test2, '') != COALESCE(null, ''))) AND (test1 >= 2) ORDER BY `test1` ASC, `test2` DESC LIMIT 200",
 | 
				
			||||||
| 
						 | 
					@ -300,7 +300,7 @@ func TestProviderExecNonEmptyQuery(t *testing.T) {
 | 
				
			||||||
			[]FilterData{"test3 != ''"},
 | 
								[]FilterData{"test3 != ''"},
 | 
				
			||||||
			"",
 | 
								"",
 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
			`{"page":1,"perPage":10,"totalItems":0,"items":[]}`,
 | 
								`{"page":1,"perPage":10,"totalItems":0,"totalPages":0,"items":[]}`,
 | 
				
			||||||
			[]string{
 | 
								[]string{
 | 
				
			||||||
				"SELECT COUNT(*) FROM `test` WHERE (NOT (`test1` IS NULL)) AND (COALESCE(test3, '') != COALESCE('', '')) ORDER BY `test1` ASC, `test3` ASC",
 | 
									"SELECT COUNT(*) FROM `test` WHERE (NOT (`test1` IS NULL)) AND (COALESCE(test3, '') != COALESCE('', '')) ORDER BY `test1` ASC, `test3` ASC",
 | 
				
			||||||
				"SELECT * FROM `test` WHERE (NOT (`test1` IS NULL)) AND (COALESCE(test3, '') != COALESCE('', '')) ORDER BY `test1` ASC, `test3` ASC LIMIT 10",
 | 
									"SELECT * FROM `test` WHERE (NOT (`test1` IS NULL)) AND (COALESCE(test3, '') != COALESCE('', '')) ORDER BY `test1` ASC, `test3` ASC LIMIT 10",
 | 
				
			||||||
| 
						 | 
					@ -314,7 +314,7 @@ func TestProviderExecNonEmptyQuery(t *testing.T) {
 | 
				
			||||||
			[]FilterData{},
 | 
								[]FilterData{},
 | 
				
			||||||
			"",
 | 
								"",
 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
			`{"page":2,"perPage":1,"totalItems":2,"items":[{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
								`{"page":2,"perPage":1,"totalItems":2,"totalPages":2,"items":[{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
				
			||||||
			[]string{
 | 
								[]string{
 | 
				
			||||||
				"SELECT COUNT(*) FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC",
 | 
									"SELECT COUNT(*) FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC",
 | 
				
			||||||
				"SELECT * FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC LIMIT 1 OFFSET 1",
 | 
									"SELECT * FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC LIMIT 1 OFFSET 1",
 | 
				
			||||||
| 
						 | 
					@ -328,7 +328,7 @@ func TestProviderExecNonEmptyQuery(t *testing.T) {
 | 
				
			||||||
			[]FilterData{},
 | 
								[]FilterData{},
 | 
				
			||||||
			"test.test1",
 | 
								"test.test1",
 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
			`{"page":2,"perPage":1,"totalItems":2,"items":[{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
								`{"page":2,"perPage":1,"totalItems":2,"totalPages":2,"items":[{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
				
			||||||
			[]string{
 | 
								[]string{
 | 
				
			||||||
				"SELECT COUNT(DISTINCT(test.test1)) FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC",
 | 
									"SELECT COUNT(DISTINCT(test.test1)) FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC",
 | 
				
			||||||
				"SELECT * FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC LIMIT 1 OFFSET 1",
 | 
									"SELECT * FROM `test` WHERE NOT (`test1` IS NULL) ORDER BY `test1` ASC LIMIT 1 OFFSET 1",
 | 
				
			||||||
| 
						 | 
					@ -403,7 +403,7 @@ func TestProviderParseAndExec(t *testing.T) {
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"",
 | 
								"",
 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
			`{"page":1,"perPage":123,"totalItems":2,"items":[{"test1":1,"test2":"test2.1","test3":""},{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
								`{"page":1,"perPage":123,"totalItems":2,"totalPages":1,"items":[{"test1":1,"test2":"test2.1","test3":""},{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		// invalid query
 | 
							// invalid query
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -439,7 +439,7 @@ func TestProviderParseAndExec(t *testing.T) {
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"page=3&perPage=555&filter=test1>1&sort=-test2,test3",
 | 
								"page=3&perPage=555&filter=test1>1&sort=-test2,test3",
 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
			`{"page":1,"perPage":200,"totalItems":1,"items":[{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
								`{"page":1,"perPage":200,"totalItems":1,"totalPages":1,"items":[{"test1":2,"test2":"test2.2","test3":""}]}`,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue