Add db.ToSQL method for generate SQL string.
This commit is contained in:
		
							parent
							
								
									413fe587c6
								
							
						
					
					
						commit
						4cd089df1d
					
				
							
								
								
									
										15
									
								
								gorm.go
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								gorm.go
									
									
									
									
									
								
							@ -439,3 +439,18 @@ func (db *DB) Use(plugin Plugin) error {
 | 
				
			|||||||
	db.Plugins[name] = plugin
 | 
						db.Plugins[name] = plugin
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ToSQL for generate SQL string.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// db.ToSQL(func(tx *gorm.DB) *gorm.DB {
 | 
				
			||||||
 | 
					// 		return tx.Model(&User{}).Where(&User{Name: "foo", Age: 20})
 | 
				
			||||||
 | 
					// 			.Limit(10).Offset(5)
 | 
				
			||||||
 | 
					//			.Order("name ASC")
 | 
				
			||||||
 | 
					//			.First(&User{})
 | 
				
			||||||
 | 
					// })
 | 
				
			||||||
 | 
					func (db *DB) ToSQL(queryFn func(tx *DB) *DB) string {
 | 
				
			||||||
 | 
						tx := queryFn(db.Session(&Session{DryRun: true}))
 | 
				
			||||||
 | 
						stmt := tx.Statement
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return db.Dialector.Explain(stmt.SQL.String(), stmt.Vars...)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,8 @@ import (
 | 
				
			|||||||
	"gorm.io/gorm"
 | 
						"gorm.io/gorm"
 | 
				
			||||||
	"gorm.io/gorm/clause"
 | 
						"gorm.io/gorm/clause"
 | 
				
			||||||
	. "gorm.io/gorm/utils/tests"
 | 
						. "gorm.io/gorm/utils/tests"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestRow(t *testing.T) {
 | 
					func TestRow(t *testing.T) {
 | 
				
			||||||
@ -287,3 +289,109 @@ func TestFromWithJoins(t *testing.T) {
 | 
				
			|||||||
		t.Errorf("The first join condition is over written instead of combining")
 | 
							t.Errorf("The first join condition is over written instead of combining")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestToSQL(t *testing.T) {
 | 
				
			||||||
 | 
						// only test in PostgreSQL
 | 
				
			||||||
 | 
						var dialect = os.Getenv("GORM_DIALECT")
 | 
				
			||||||
 | 
						if dialect != "postgres" {
 | 
				
			||||||
 | 
							t.Skipf("Skipping test for %s database", dialect)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// By default DB.DryRun should false
 | 
				
			||||||
 | 
						if DB.DryRun {
 | 
				
			||||||
 | 
							t.Fatal("Failed expect DB.DryRun to be false")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						date, _ := time.Parse("2006-01-02", "2021-10-18")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// find
 | 
				
			||||||
 | 
						sql := DB.ToSQL(func(tx *gorm.DB) *gorm.DB {
 | 
				
			||||||
 | 
							return tx.Model(&User{}).Where("id = ?", 100).Limit(10).Order("age desc").Find(&[]User{})
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						assertEqualSQL(t, `SELECT * FROM "users" WHERE id = 100 AND "users"."deleted_at" IS NULL ORDER BY age desc LIMIT 10`, sql)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// after model chagned
 | 
				
			||||||
 | 
						if DB.Statement.DryRun || DB.DryRun {
 | 
				
			||||||
 | 
							t.Fatal("Failed expect DB.DryRun and DB.Statement.ToSQL to be false")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if DB.Statement.SQL.String() != "" {
 | 
				
			||||||
 | 
							t.Fatal("Failed expect DB.Statement.SQL to be empty")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// first
 | 
				
			||||||
 | 
						sql = DB.ToSQL(func(tx *gorm.DB) *gorm.DB {
 | 
				
			||||||
 | 
							return tx.Model(&User{}).Where(&User{Name: "foo", Age: 20}).Limit(10).Offset(5).Order("name ASC").First(&User{})
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						assertEqualSQL(t, `SELECT * FROM "users" WHERE "users"."name" = 'foo' AND "users"."age" = 20 AND "users"."deleted_at" IS NULL ORDER BY name ASC,"users"."id" LIMIT 1 OFFSET 5`, sql)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// last and unscoped
 | 
				
			||||||
 | 
						sql = DB.ToSQL(func(tx *gorm.DB) *gorm.DB {
 | 
				
			||||||
 | 
							return tx.Model(&User{}).Unscoped().Where(&User{Name: "bar", Age: 12}).Limit(10).Offset(5).Order("name ASC").Last(&User{})
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						assertEqualSQL(t, `SELECT * FROM "users" WHERE "users"."name" = 'bar' AND "users"."age" = 12 ORDER BY name ASC,"users"."id" DESC LIMIT 1 OFFSET 5`, sql)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// create
 | 
				
			||||||
 | 
						user := &User{Name: "foo", Age: 20}
 | 
				
			||||||
 | 
						user.CreatedAt = date
 | 
				
			||||||
 | 
						user.UpdatedAt = date
 | 
				
			||||||
 | 
						sql = DB.ToSQL(func(tx *gorm.DB) *gorm.DB {
 | 
				
			||||||
 | 
							return tx.Model(&User{}).Create(user)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						assertEqualSQL(t, `INSERT INTO "users" ("created_at","updated_at","deleted_at","name","age","birthday","company_id","manager_id","active") VALUES ('2021-10-18 00:00:00','2021-10-18 00:00:00',NULL,'foo',20,NULL,NULL,NULL,false) RETURNING "id"`, sql)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// save
 | 
				
			||||||
 | 
						user = &User{Name: "foo", Age: 20}
 | 
				
			||||||
 | 
						user.CreatedAt = date
 | 
				
			||||||
 | 
						user.UpdatedAt = date
 | 
				
			||||||
 | 
						sql = DB.ToSQL(func(tx *gorm.DB) *gorm.DB {
 | 
				
			||||||
 | 
							return tx.Model(&User{}).Save(user)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						assertEqualSQL(t, `INSERT INTO "users" ("created_at","updated_at","deleted_at","name","age","birthday","company_id","manager_id","active") VALUES ('2021-10-18 00:00:00','2021-10-18 00:00:00',NULL,'foo',20,NULL,NULL,NULL,false) RETURNING "id"`, sql)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// updates
 | 
				
			||||||
 | 
						user = &User{Name: "bar", Age: 22}
 | 
				
			||||||
 | 
						user.CreatedAt = date
 | 
				
			||||||
 | 
						user.UpdatedAt = date
 | 
				
			||||||
 | 
						sql = DB.ToSQL(func(tx *gorm.DB) *gorm.DB {
 | 
				
			||||||
 | 
							return tx.Model(&User{}).Where("id = ?", 100).Updates(user)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						assertEqualSQL(t, `UPDATE "users" SET "created_at"='2021-10-18 00:00:00',"updated_at"='2021-10-18 19:50:09.438',"name"='bar',"age"=22 WHERE id = 100 AND "users"."deleted_at" IS NULL`, sql)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// update
 | 
				
			||||||
 | 
						sql = DB.ToSQL(func(tx *gorm.DB) *gorm.DB {
 | 
				
			||||||
 | 
							return tx.Model(&User{}).Where("id = ?", 100).Update("name", "Foo bar")
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						assertEqualSQL(t, `UPDATE "users" SET "name"='Foo bar',"updated_at"='2021-10-18 19:50:09.438' WHERE id = 100 AND "users"."deleted_at" IS NULL`, sql)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// UpdateColumn
 | 
				
			||||||
 | 
						sql = DB.ToSQL(func(tx *gorm.DB) *gorm.DB {
 | 
				
			||||||
 | 
							return tx.Model(&User{}).Where("id = ?", 100).UpdateColumn("name", "Foo bar")
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						assertEqualSQL(t, `UPDATE "users" SET "name"='Foo bar' WHERE id = 100 AND "users"."deleted_at" IS NULL`, sql)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// UpdateColumns
 | 
				
			||||||
 | 
						sql = DB.ToSQL(func(tx *gorm.DB) *gorm.DB {
 | 
				
			||||||
 | 
							return tx.Model(&User{}).Where("id = ?", 100).UpdateColumns(User{Name: "Foo", Age: 100})
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						assertEqualSQL(t, `UPDATE "users" SET "name"='Foo',"age"=100 WHERE id = 100 AND "users"."deleted_at" IS NULL`, sql)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// after model chagned
 | 
				
			||||||
 | 
						if DB.Statement.DryRun || DB.DryRun {
 | 
				
			||||||
 | 
							t.Fatal("Failed expect DB.DryRun and DB.Statement.ToSQL to be false")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func assertEqualSQL(t *testing.T, expected string, actually string) {
 | 
				
			||||||
 | 
						t.Helper()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ignore updated_at value
 | 
				
			||||||
 | 
						var updatedAtRe = regexp.MustCompile(`"updated_at"='.+?'`)
 | 
				
			||||||
 | 
						actually = updatedAtRe.ReplaceAllString(actually, `"updated_at"='?'`)
 | 
				
			||||||
 | 
						expected = updatedAtRe.ReplaceAllString(expected, `"updated_at"='?'`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if actually != expected {
 | 
				
			||||||
 | 
							t.Fatalf("Failed generate save SQL\nexpected: %s\nactually: %s", expected, actually)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user